diff --git a/autoadmin-ws-server/src/index.ts b/autoadmin-ws-server/src/index.ts index 304a3541b..68856f14a 100644 --- a/autoadmin-ws-server/src/index.ts +++ b/autoadmin-ws-server/src/index.ts @@ -5,7 +5,6 @@ import { config, validateConfig } from './config.js'; import { setupWebSocketServer } from './handlers/websocket.js'; import { logger } from './utils/logger.js'; -// Validate configuration try { validateConfig(); } catch (error) { @@ -16,7 +15,6 @@ try { const app = createApp(); -// Create HTTP server for Hono const httpServer = serve({ fetch: app.fetch, port: config.httpPort, @@ -36,11 +34,9 @@ wsHttpServer.listen(config.wsPort, () => { logger.info({ port: config.wsPort }, 'WebSocket server started'); }); -// Graceful shutdown const shutdown = (signal: string) => { logger.info({ signal }, 'Shutdown signal received'); - // Close WebSocket server wss.close(() => { logger.info('WebSocket server closed'); }); @@ -49,12 +45,10 @@ const shutdown = (signal: string) => { logger.info('WebSocket HTTP server closed'); }); - // Close HTTP server httpServer.close(() => { logger.info('HTTP server closed'); }); - // Give connections time to close gracefully setTimeout(() => { logger.info('Forcing shutdown'); process.exit(0); @@ -64,7 +58,6 @@ const shutdown = (signal: string) => { process.on('SIGTERM', () => shutdown('SIGTERM')); process.on('SIGINT', () => shutdown('SIGINT')); -// Handle uncaught errors process.on('uncaughtException', (error) => { logger.fatal({ error: error.message, stack: error.stack }, 'Uncaught exception'); process.exit(1); diff --git a/backend/_force-exit.mjs b/backend/_force-exit.mjs index ca3e7c1cd..8859b64b5 100644 --- a/backend/_force-exit.mjs +++ b/backend/_force-exit.mjs @@ -2,5 +2,5 @@ import process from 'node:process'; import { registerCompletionHandler } from 'ava'; registerCompletionHandler(() => { - process.exit(); + process.exit(); }); diff --git a/backend/ava.config.mjs b/backend/ava.config.mjs index ed404e499..0d6b94363 100644 --- a/backend/ava.config.mjs +++ b/backend/ava.config.mjs @@ -1,18 +1,17 @@ - export default { - require: ['./_force-exit.mjs'], - files: ['test/ava-tests/**'], - typescript: { - extensions: ['ts'], - rewritePaths: { - 'src/': 'dist/src/', - 'test/': 'dist/test/', - }, - compile: false, - }, - workerThreads: false, - verbose: true, - timeout: '5m', - failFast: false, - concurrency: 3, + require: ['./_force-exit.mjs'], + files: ['test/ava-tests/**'], + typescript: { + extensions: ['ts'], + rewritePaths: { + 'src/': 'dist/src/', + 'test/': 'dist/test/', + }, + compile: false, + }, + workerThreads: false, + verbose: true, + timeout: '5m', + failFast: false, + concurrency: 3, }; diff --git a/backend/knip.json b/backend/knip.json index b605ec3c6..70ac82f3e 100644 --- a/backend/knip.json +++ b/backend/knip.json @@ -1,9 +1,9 @@ { - "$schema": "https://unpkg.com/knip@5/schema.json", - "ignoreExportsUsedInFile": { - "interface": true, - "type": true - }, - "ignore": ["src/migrations/**", "src/shared/config/datasource.config.ts", "src/enums/widget-type.enum.ts"], - "tags": ["-lintignore"] + "$schema": "https://unpkg.com/knip@5/schema.json", + "ignoreExportsUsedInFile": { + "interface": true, + "type": true + }, + "ignore": ["src/migrations/**", "src/shared/config/datasource.config.ts", "src/enums/widget-type.enum.ts"], + "tags": ["-lintignore"] } diff --git a/backend/nest-cli.json b/backend/nest-cli.json index e64c4946c..020ed8f24 100644 --- a/backend/nest-cli.json +++ b/backend/nest-cli.json @@ -1,8 +1,8 @@ { - "monorepo": true, - "collection": "@nestjs/schematics", - "compilerOptions": { - "plugins": [] - }, - "sourceRoot": "src" + "monorepo": true, + "collection": "@nestjs/schematics", + "compilerOptions": { + "plugins": [] + }, + "sourceRoot": "src" } diff --git a/backend/src/ai-core/ai-core.module.ts b/backend/src/ai-core/ai-core.module.ts index d9fae60fb..58cc64e1f 100644 --- a/backend/src/ai-core/ai-core.module.ts +++ b/backend/src/ai-core/ai-core.module.ts @@ -1,6 +1,6 @@ import { Global, Module } from '@nestjs/common'; -import { LangchainOpenAIProvider } from './providers/langchain-openai.provider.js'; import { LangchainBedrockProvider } from './providers/langchain-bedrock.provider.js'; +import { LangchainOpenAIProvider } from './providers/langchain-openai.provider.js'; import { AICoreService } from './services/ai-core.service.js'; export const AI_CORE_SERVICE = 'AI_CORE_SERVICE'; diff --git a/backend/src/ai-core/interfaces/ai-service.interface.ts b/backend/src/ai-core/interfaces/ai-service.interface.ts index 8f6149acc..fd8dadd3c 100644 --- a/backend/src/ai-core/interfaces/ai-service.interface.ts +++ b/backend/src/ai-core/interfaces/ai-service.interface.ts @@ -1,4 +1,5 @@ import { BaseMessage } from '@langchain/core/messages'; +import { IterableReadableStream } from '@langchain/core/utils/stream'; import { AICompletionResult, AIProviderConfig, @@ -6,7 +7,6 @@ import { AIToolDefinition, AIToolResult, } from './ai-provider.interface.js'; -import { IterableReadableStream } from '@langchain/core/utils/stream'; export enum AIProviderType { OPENAI = 'openai', @@ -14,7 +14,6 @@ export enum AIProviderType { } export interface IAIService { - complete(prompt: string, config?: AIProviderConfig): Promise; completeWithProvider(provider: AIProviderType, prompt: string, config?: AIProviderConfig): Promise; diff --git a/backend/src/ai-core/providers/index.ts b/backend/src/ai-core/providers/index.ts index e6527c1f5..2355df78c 100644 --- a/backend/src/ai-core/providers/index.ts +++ b/backend/src/ai-core/providers/index.ts @@ -1,2 +1,2 @@ -export * from './langchain-openai.provider.js'; export * from './langchain-bedrock.provider.js'; +export * from './langchain-openai.provider.js'; diff --git a/backend/src/ai-core/providers/langchain-bedrock.provider.ts b/backend/src/ai-core/providers/langchain-bedrock.provider.ts index 5ebfe5b7f..7a8ca36b0 100644 --- a/backend/src/ai-core/providers/langchain-bedrock.provider.ts +++ b/backend/src/ai-core/providers/langchain-bedrock.provider.ts @@ -1,17 +1,17 @@ -import { Injectable } from '@nestjs/common'; import { ChatBedrockConverse } from '@langchain/aws'; -import { BaseMessage, AIMessage, AIMessageChunk, HumanMessage, ToolMessage } from '@langchain/core/messages'; -import { IterableReadableStream } from '@langchain/core/utils/stream'; +import { AIMessage, AIMessageChunk, BaseMessage, HumanMessage, ToolMessage } from '@langchain/core/messages'; import { tool } from '@langchain/core/tools'; +import { IterableReadableStream } from '@langchain/core/utils/stream'; +import { Injectable } from '@nestjs/common'; import { z } from 'zod'; import { - IAIProvider, - AIProviderConfig, AICompletionResult, + AIProviderConfig, AIStreamChunk, + AIToolCall, AIToolDefinition, AIToolResult, - AIToolCall, + IAIProvider, } from '../interfaces/ai-provider.interface.js'; @Injectable() diff --git a/backend/src/ai-core/providers/langchain-openai.provider.ts b/backend/src/ai-core/providers/langchain-openai.provider.ts index 8410105d7..ddd7bf74f 100644 --- a/backend/src/ai-core/providers/langchain-openai.provider.ts +++ b/backend/src/ai-core/providers/langchain-openai.provider.ts @@ -1,20 +1,20 @@ -import { Injectable } from '@nestjs/common'; -import { ChatOpenAI } from '@langchain/openai'; -import { BaseMessage, AIMessage, AIMessageChunk, HumanMessage, ToolMessage } from '@langchain/core/messages'; -import { IterableReadableStream } from '@langchain/core/utils/stream'; +import { AIMessage, AIMessageChunk, BaseMessage, HumanMessage, ToolMessage } from '@langchain/core/messages'; import { tool } from '@langchain/core/tools'; -import { z } from 'zod'; +import { IterableReadableStream } from '@langchain/core/utils/stream'; +import { ChatOpenAI } from '@langchain/openai'; +import { Injectable } from '@nestjs/common'; import OpenAI from 'openai'; +import { z } from 'zod'; +import { getOptionalEnvVariable, getRequiredEnvVariable } from '../../helpers/app/get-requeired-env-variable.js'; import { - IAIProvider, - AIProviderConfig, AICompletionResult, + AIProviderConfig, AIStreamChunk, + AIToolCall, AIToolDefinition, AIToolResult, - AIToolCall, + IAIProvider, } from '../interfaces/ai-provider.interface.js'; -import { getOptionalEnvVariable, getRequiredEnvVariable } from '../../helpers/app/get-requeired-env-variable.js'; @Injectable() export class LangchainOpenAIProvider implements IAIProvider { diff --git a/backend/src/ai-core/services/ai-core.service.ts b/backend/src/ai-core/services/ai-core.service.ts index b301ce449..7f4a630ce 100644 --- a/backend/src/ai-core/services/ai-core.service.ts +++ b/backend/src/ai-core/services/ai-core.service.ts @@ -1,17 +1,17 @@ -import { Injectable } from '@nestjs/common'; import { BaseMessage } from '@langchain/core/messages'; import { IterableReadableStream } from '@langchain/core/utils/stream'; -import { IAIService, AIProviderType } from '../interfaces/ai-service.interface.js'; +import { Injectable } from '@nestjs/common'; import { - AIProviderConfig, AICompletionResult, + AIProviderConfig, AIStreamChunk, AIToolDefinition, AIToolResult, IAIProvider, } from '../interfaces/ai-provider.interface.js'; -import { LangchainOpenAIProvider } from '../providers/langchain-openai.provider.js'; +import { AIProviderType, IAIService } from '../interfaces/ai-service.interface.js'; import { LangchainBedrockProvider } from '../providers/langchain-bedrock.provider.js'; +import { LangchainOpenAIProvider } from '../providers/langchain-openai.provider.js'; @Injectable() export class AICoreService implements IAIService { diff --git a/backend/src/ai-core/utils/message-builder.ts b/backend/src/ai-core/utils/message-builder.ts index a3f14882e..10b431117 100644 --- a/backend/src/ai-core/utils/message-builder.ts +++ b/backend/src/ai-core/utils/message-builder.ts @@ -1,4 +1,4 @@ -import { HumanMessage, SystemMessage, AIMessage, ToolMessage, BaseMessage } from '@langchain/core/messages'; +import { AIMessage, BaseMessage, HumanMessage, SystemMessage, ToolMessage } from '@langchain/core/messages'; import { AIToolCall } from '../interfaces/ai-provider.interface.js'; export class MessageBuilder { diff --git a/backend/src/app.module.ts b/backend/src/app.module.ts index 88edb710a..754dd0d90 100644 --- a/backend/src/app.module.ts +++ b/backend/src/app.module.ts @@ -2,8 +2,8 @@ import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common'; import { APP_GUARD } from '@nestjs/core'; import { ScheduleModule } from '@nestjs/schedule'; import { ThrottlerGuard, ThrottlerModule } from '@nestjs/throttler'; -import { AppController } from './app.controller.js'; import { AICoreModule } from './ai-core/ai-core.module.js'; +import { AppController } from './app.controller.js'; import { GlobalDatabaseContext } from './common/application/global-database-context.js'; import { BaseType, UseCaseType } from './common/data-injection.tokens.js'; import { AIModule } from './entities/ai/ai.module.js'; @@ -31,23 +31,22 @@ import { TableCategoriesModule } from './entities/table-categories/table-categor import { TableFiltersModule } from './entities/table-filters/table-filters.module.js'; import { TableLogsModule } from './entities/table-logs/table-logs.module.js'; import { TableSettingsModule } from './entities/table-settings/common-table-settings/table-settings.module.js'; +import { PersonalTableSettingsModule } from './entities/table-settings/personal-table-settings/personal-table-settings.module.js'; import { UserModule } from './entities/user/user.module.js'; import { UserActionModule } from './entities/user-actions/user-action.module.js'; import { UserSecretModule } from './entities/user-secret/user-secret.module.js'; import { SignInAuditModule } from './entities/user-sign-in-audit/sign-in-audit.module.js'; +import { DashboardModule } from './entities/visualizations/dashboard/dashboards.module.js'; +import { DashboardWidgetModule } from './entities/visualizations/dashboard-widget/dashboard-widget.module.js'; +import { SavedDbQueryModule } from './entities/visualizations/saved-db-query/saved-db-query.module.js'; import { TableWidgetModule } from './entities/widget/table-widget.module.js'; - import { SaaSGatewayModule } from './microservices/gateways/saas-gateway.ts/saas-gateway.module.js'; import { SaasModule } from './microservices/saas-microservice/saas.module.js'; import { AppLoggerMiddleware } from './middlewares/logging-middleware/app-logger-middlewate.js'; +import { SelfHostedOperationsModule } from './selfhosted-operations/selhosted-operations.module.js'; import { DatabaseModule } from './shared/database/database.module.js'; import { SharedModule } from './shared/shared.module.js'; import { GetHelloUseCase } from './use-cases-app/get-hello.use.case.js'; -import { PersonalTableSettingsModule } from './entities/table-settings/personal-table-settings/personal-table-settings.module.js'; -import { SavedDbQueryModule } from './entities/visualizations/saved-db-query/saved-db-query.module.js'; -import { DashboardModule } from './entities/visualizations/dashboard/dashboards.module.js'; -import { DashboardWidgetModule } from './entities/visualizations/dashboard-widget/dashboard-widget.module.js'; -import { SelfHostedOperationsModule } from './selfhosted-operations/selhosted-operations.module.js'; @Module({ imports: [ diff --git a/backend/src/authorization/basic-auth.middleware.ts b/backend/src/authorization/basic-auth.middleware.ts index fe5804aef..6512e2ffe 100644 --- a/backend/src/authorization/basic-auth.middleware.ts +++ b/backend/src/authorization/basic-auth.middleware.ts @@ -1,22 +1,22 @@ import { Injectable, NestMiddleware, UnauthorizedException } from '@nestjs/common'; -import { Request, Response } from 'express'; import auth from 'basic-auth'; +import { Request, Response } from 'express'; import { Messages } from '../exceptions/text/messages.js'; @Injectable() export class BasicAuthMiddleware implements NestMiddleware { - use(req: Request, _res: Response, next: (err?: any, res?: any) => void): void { - const basicAuthLogin = process.env.BASIC_AUTH_LOGIN; - const basicAuthPassword = process.env.BASIC_AUTH_PWD; - const userCredentials = auth(req); - if (!userCredentials) { - throw new UnauthorizedException(Messages.AUTHORIZATION_REQUIRED); - } - const { name: loginUserName, pass: loginUserPassword } = userCredentials; - if (basicAuthLogin !== loginUserName || basicAuthPassword !== loginUserPassword) { - throw new UnauthorizedException(Messages.INVALID_USERNAME_OR_PASSWORD); - } else { - next(); - } - } + use(req: Request, _res: Response, next: (err?: any, res?: any) => void): void { + const basicAuthLogin = process.env.BASIC_AUTH_LOGIN; + const basicAuthPassword = process.env.BASIC_AUTH_PWD; + const userCredentials = auth(req); + if (!userCredentials) { + throw new UnauthorizedException(Messages.AUTHORIZATION_REQUIRED); + } + const { name: loginUserName, pass: loginUserPassword } = userCredentials; + if (basicAuthLogin !== loginUserName || basicAuthPassword !== loginUserPassword) { + throw new UnauthorizedException(Messages.INVALID_USERNAME_OR_PASSWORD); + } else { + next(); + } + } } diff --git a/backend/src/authorization/cognito-decoded.interface.ts b/backend/src/authorization/cognito-decoded.interface.ts index 926870a87..431b37940 100644 --- a/backend/src/authorization/cognito-decoded.interface.ts +++ b/backend/src/authorization/cognito-decoded.interface.ts @@ -1,21 +1,21 @@ import type { Request } from 'express'; export interface ICognitoDecodedData { - at_hash: string; - sub: string; - aud: string | string[]; - email_verified: boolean; - event_id: string; - token_use: string; - auth_time: number; - iss: string; - 'cognito:username': string; - exp: number; - iat: number; - email: string; + at_hash: string; + sub: string; + aud: string | string[]; + email_verified: boolean; + event_id: string; + token_use: string; + auth_time: number; + iss: string; + 'cognito:username': string; + exp: number; + iat: number; + email: string; } export interface IRequestWithCognitoInfo extends Request { - query: any; - decoded: Partial; - params: any; + query: any; + decoded: Partial; + params: any; } diff --git a/backend/src/authorization/non-scoped-auth.middleware.ts b/backend/src/authorization/non-scoped-auth.middleware.ts index 0b5c9a4c7..29c50a588 100644 --- a/backend/src/authorization/non-scoped-auth.middleware.ts +++ b/backend/src/authorization/non-scoped-auth.middleware.ts @@ -1,72 +1,72 @@ import { - HttpException, - Injectable, - InternalServerErrorException, - NestMiddleware, - UnauthorizedException, + HttpException, + Injectable, + InternalServerErrorException, + NestMiddleware, + UnauthorizedException, } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; +import Sentry from '@sentry/minimal'; import { Response } from 'express'; import jwt from 'jsonwebtoken'; import { Repository } from 'typeorm'; import { LogOutEntity } from '../entities/log-out/log-out.entity.js'; import { Messages } from '../exceptions/text/messages.js'; -import { isObjectEmpty } from '../helpers/index.js'; import { Constants } from '../helpers/constants/constants.js'; -import Sentry from '@sentry/minimal'; +import { isObjectEmpty } from '../helpers/index.js'; import { IRequestWithCognitoInfo } from './cognito-decoded.interface.js'; @Injectable() export class NonScopedAuthMiddleware implements NestMiddleware { - public constructor( - @InjectRepository(LogOutEntity) - private readonly logOutRepository: Repository, - ) {} - async use(req: IRequestWithCognitoInfo, _res: Response, next: (err?: any, res?: any) => void): Promise { - console.log(`auth middleware triggered ->: ${new Date().toISOString()}`); - let token: string; - try { - token = req.cookies[Constants.JWT_COOKIE_KEY_NAME]; - } catch (_e) { - if (process.env.NODE_ENV !== 'test') { - throw new UnauthorizedException('JWT verification failed'); - } - } + public constructor( + @InjectRepository(LogOutEntity) + private readonly logOutRepository: Repository, + ) {} + async use(req: IRequestWithCognitoInfo, _res: Response, next: (err?: any, res?: any) => void): Promise { + console.log(`auth middleware triggered ->: ${new Date().toISOString()}`); + let token: string; + try { + token = req.cookies[Constants.JWT_COOKIE_KEY_NAME]; + } catch (_e) { + if (process.env.NODE_ENV !== 'test') { + throw new UnauthorizedException('JWT verification failed'); + } + } - if (!token) { - throw new UnauthorizedException('Token is missing'); - } + if (!token) { + throw new UnauthorizedException('Token is missing'); + } - const isLoggedOut = !!(await this.logOutRepository.findOne({ where: { jwtToken: token } })); - if (isLoggedOut) { - throw new UnauthorizedException('JWT verification failed'); - } + const isLoggedOut = !!(await this.logOutRepository.findOne({ where: { jwtToken: token } })); + if (isLoggedOut) { + throw new UnauthorizedException('JWT verification failed'); + } - try { - const jwtSecret = process.env.JWT_SECRET; - const data = jwt.verify(token, jwtSecret) as jwt.JwtPayload; - const userId = data.id; - if (!userId) { - throw new UnauthorizedException('JWT verification failed'); - } + try { + const jwtSecret = process.env.JWT_SECRET; + const data = jwt.verify(token, jwtSecret) as jwt.JwtPayload; + const userId = data.id; + if (!userId) { + throw new UnauthorizedException('JWT verification failed'); + } - const payload = { - sub: userId, - email: data.email, - exp: data.exp, - iat: data.iat, - }; - if (!payload || isObjectEmpty(payload)) { - throw new UnauthorizedException('JWT verification failed'); - } - req.decoded = payload; - next(); - } catch (e) { - Sentry.captureException(e); - if (e instanceof HttpException || e instanceof UnauthorizedException) { - throw e; - } - throw new InternalServerErrorException(Messages.AUTHORIZATION_REJECTED); - } - } + const payload = { + sub: userId, + email: data.email, + exp: data.exp, + iat: data.iat, + }; + if (!payload || isObjectEmpty(payload)) { + throw new UnauthorizedException('JWT verification failed'); + } + req.decoded = payload; + next(); + } catch (e) { + Sentry.captureException(e); + if (e instanceof HttpException || e instanceof UnauthorizedException) { + throw e; + } + throw new InternalServerErrorException(Messages.AUTHORIZATION_REJECTED); + } + } } diff --git a/backend/src/authorization/saas-auth.middleware.ts b/backend/src/authorization/saas-auth.middleware.ts index 6cd2a1fb2..95002ed6a 100644 --- a/backend/src/authorization/saas-auth.middleware.ts +++ b/backend/src/authorization/saas-auth.middleware.ts @@ -2,30 +2,30 @@ import { Injectable, NestMiddleware, UnauthorizedException } from '@nestjs/commo import { Response } from 'express'; import jwt from 'jsonwebtoken'; import { Messages } from '../exceptions/text/messages.js'; -import { extractTokenFromHeader } from './utils/extract-token-from-header.js'; import { IRequestWithCognitoInfo } from './cognito-decoded.interface.js'; +import { extractTokenFromHeader } from './utils/extract-token-from-header.js'; @Injectable() export class SaaSAuthMiddleware implements NestMiddleware { - use(req: IRequestWithCognitoInfo, _res: Response, next: (err?: any, res?: any) => void): void { - console.log(`saas auth middleware triggered ->: ${new Date().toISOString()}`); - const token = extractTokenFromHeader(req); - if (!token) { - throw new UnauthorizedException('Token is missing'); - } - try { - const jwtSecret = process.env.MICROSERVICE_JWT_SECRET; - const data = jwt.verify(token, jwtSecret) as jwt.JwtPayload; - const requestId = data.request_id; + use(req: IRequestWithCognitoInfo, _res: Response, next: (err?: any, res?: any) => void): void { + console.log(`saas auth middleware triggered ->: ${new Date().toISOString()}`); + const token = extractTokenFromHeader(req); + if (!token) { + throw new UnauthorizedException('Token is missing'); + } + try { + const jwtSecret = process.env.MICROSERVICE_JWT_SECRET; + const data = jwt.verify(token, jwtSecret) as jwt.JwtPayload; + const requestId = data.request_id; - if (!requestId) { - throw new UnauthorizedException(Messages.AUTHORIZATION_REJECTED); - } + if (!requestId) { + throw new UnauthorizedException(Messages.AUTHORIZATION_REJECTED); + } - req.decoded = data; - next(); - } catch (_e) { - throw new UnauthorizedException(Messages.AUTHORIZATION_REJECTED); - } - } + req.decoded = data; + next(); + } catch (_e) { + throw new UnauthorizedException(Messages.AUTHORIZATION_REJECTED); + } + } } diff --git a/backend/src/authorization/temporary-auth.middleware.ts b/backend/src/authorization/temporary-auth.middleware.ts index 8b60cbb10..4ec1cc621 100644 --- a/backend/src/authorization/temporary-auth.middleware.ts +++ b/backend/src/authorization/temporary-auth.middleware.ts @@ -1,73 +1,73 @@ import { - HttpException, - Injectable, - InternalServerErrorException, - NestMiddleware, - UnauthorizedException, + HttpException, + Injectable, + InternalServerErrorException, + NestMiddleware, + UnauthorizedException, } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; +import Sentry from '@sentry/minimal'; import { Response } from 'express'; import jwt from 'jsonwebtoken'; import { Repository } from 'typeorm'; import { LogOutEntity } from '../entities/log-out/log-out.entity.js'; import { UserEntity } from '../entities/user/user.entity.js'; import { Messages } from '../exceptions/text/messages.js'; -import { isObjectEmpty } from '../helpers/index.js'; -import Sentry from '@sentry/minimal'; import { Constants } from '../helpers/constants/constants.js'; +import { isObjectEmpty } from '../helpers/index.js'; import { IRequestWithCognitoInfo } from './cognito-decoded.interface.js'; @Injectable() export class TemporaryAuthMiddleware implements NestMiddleware { - public constructor( - @InjectRepository(UserEntity)readonly _userRepository: Repository, - @InjectRepository(LogOutEntity) - private readonly logOutRepository: Repository, - ) {} - async use(req: IRequestWithCognitoInfo, _res: Response, next: (err?: any, res?: any) => void): Promise { - console.log(`temporary auth middleware triggered ->: ${new Date().toISOString()}`); - let token: string; - try { - token = req.cookies[Constants.JWT_COOKIE_KEY_NAME]; - } catch (_e) { - if (process.env.NODE_ENV !== 'test') { - throw new UnauthorizedException('JWT verification failed'); - } - } + public constructor( + @InjectRepository(UserEntity) readonly _userRepository: Repository, + @InjectRepository(LogOutEntity) + private readonly logOutRepository: Repository, + ) {} + async use(req: IRequestWithCognitoInfo, _res: Response, next: (err?: any, res?: any) => void): Promise { + console.log(`temporary auth middleware triggered ->: ${new Date().toISOString()}`); + let token: string; + try { + token = req.cookies[Constants.JWT_COOKIE_KEY_NAME]; + } catch (_e) { + if (process.env.NODE_ENV !== 'test') { + throw new UnauthorizedException('JWT verification failed'); + } + } - if (!token) { - throw new UnauthorizedException('Token is missing'); - } + if (!token) { + throw new UnauthorizedException('Token is missing'); + } - const isLoggedOut = !!(await this.logOutRepository.findOne({ where: { jwtToken: token } })); - if (isLoggedOut) { - throw new UnauthorizedException('JWT verification failed'); - } + const isLoggedOut = !!(await this.logOutRepository.findOne({ where: { jwtToken: token } })); + if (isLoggedOut) { + throw new UnauthorizedException('JWT verification failed'); + } - try { - const jwtSecret = process.env.TEMPORARY_JWT_SECRET; - const data = jwt.verify(token, jwtSecret) as jwt.JwtPayload; - const userId = data.id; - if (!userId) { - throw new UnauthorizedException('JWT verification failed'); - } - const payload = { - sub: userId, - email: data.email, - exp: data.exp, - iat: data.iat, - }; - if (!payload || isObjectEmpty(payload)) { - throw new UnauthorizedException('JWT verification failed'); - } - req.decoded = payload; - next(); - } catch (e) { - Sentry.captureException(e); - if (e instanceof HttpException || e instanceof UnauthorizedException) { - throw e; - } - throw new InternalServerErrorException(Messages.AUTHORIZATION_REJECTED); - } - } + try { + const jwtSecret = process.env.TEMPORARY_JWT_SECRET; + const data = jwt.verify(token, jwtSecret) as jwt.JwtPayload; + const userId = data.id; + if (!userId) { + throw new UnauthorizedException('JWT verification failed'); + } + const payload = { + sub: userId, + email: data.email, + exp: data.exp, + iat: data.iat, + }; + if (!payload || isObjectEmpty(payload)) { + throw new UnauthorizedException('JWT verification failed'); + } + req.decoded = payload; + next(); + } catch (e) { + Sentry.captureException(e); + if (e instanceof HttpException || e instanceof UnauthorizedException) { + throw e; + } + throw new InternalServerErrorException(Messages.AUTHORIZATION_REJECTED); + } + } } diff --git a/backend/src/authorization/utils/extract-token-from-header.ts b/backend/src/authorization/utils/extract-token-from-header.ts index c2299db00..e559e52c5 100644 --- a/backend/src/authorization/utils/extract-token-from-header.ts +++ b/backend/src/authorization/utils/extract-token-from-header.ts @@ -1,5 +1,5 @@ import { Request } from 'express'; export const extractTokenFromHeader = (request: Request): string | null => { - const [type, token] = request.headers.authorization?.split(' ') ?? []; - return type === 'Bearer' ? token : null; + const [type, token] = request.headers.authorization?.split(' ') ?? []; + return type === 'Bearer' ? token : null; }; diff --git a/backend/src/common/abstract-use.case.ts b/backend/src/common/abstract-use.case.ts index fb713a779..36ccb095a 100644 --- a/backend/src/common/abstract-use.case.ts +++ b/backend/src/common/abstract-use.case.ts @@ -4,47 +4,47 @@ import { IDatabaseContext } from './database-context.interface.js'; @Injectable({ scope: Scope.REQUEST }) abstract class AbstractUseCase { - protected _inputData: TInputData; - protected _inTransaction: boolean; - protected abstract _dbContext: IDatabaseContext | null; - - public async execute( - inputData: TInputData, - inTransaction: InTransactionEnum = InTransactionEnum.OFF, - ): Promise { - this._inputData = inputData; - this._inTransaction = inTransaction === InTransactionEnum.ON; - - try { - if (this._inTransaction) await this.startTransaction(); - const result = await this.implementation(inputData); - if (this._inTransaction) await this.commitTransaction(); - return result; - } catch (error) { - if (this._inTransaction) await this.rollbackTransaction(); - throw error; - } finally { - if (this._inTransaction) await this.releaseQueryRunner(); - } - } - - protected abstract implementation(inputData: TInputData): Promise | TOutputData; - - private async startTransaction(): Promise { - await this._dbContext.startTransaction(); - } - - private async commitTransaction(): Promise { - await this._dbContext.commitTransaction(); - } - - private async rollbackTransaction(): Promise { - await this._dbContext.rollbackTransaction(); - } - - private async releaseQueryRunner(): Promise { - await this._dbContext.releaseQueryRunner(); - } + protected _inputData: TInputData; + protected _inTransaction: boolean; + protected abstract _dbContext: IDatabaseContext | null; + + public async execute( + inputData: TInputData, + inTransaction: InTransactionEnum = InTransactionEnum.OFF, + ): Promise { + this._inputData = inputData; + this._inTransaction = inTransaction === InTransactionEnum.ON; + + try { + if (this._inTransaction) await this.startTransaction(); + const result = await this.implementation(inputData); + if (this._inTransaction) await this.commitTransaction(); + return result; + } catch (error) { + if (this._inTransaction) await this.rollbackTransaction(); + throw error; + } finally { + if (this._inTransaction) await this.releaseQueryRunner(); + } + } + + protected abstract implementation(inputData: TInputData): Promise | TOutputData; + + private async startTransaction(): Promise { + await this._dbContext.startTransaction(); + } + + private async commitTransaction(): Promise { + await this._dbContext.commitTransaction(); + } + + private async rollbackTransaction(): Promise { + await this._dbContext.rollbackTransaction(); + } + + private async releaseQueryRunner(): Promise { + await this._dbContext.releaseQueryRunner(); + } } -export default AbstractUseCase; \ No newline at end of file +export default AbstractUseCase; diff --git a/backend/src/common/application/global-database-context.interface.ts b/backend/src/common/application/global-database-context.interface.ts index 0db8b7407..8832f21aa 100644 --- a/backend/src/common/application/global-database-context.interface.ts +++ b/backend/src/common/application/global-database-context.interface.ts @@ -1,7 +1,11 @@ import { Repository } from 'typeorm'; import { IAgentRepository } from '../../entities/agent/repository/agent.repository.interface.js'; -import { IAiResponsesToUserRepository } from '../../entities/ai/ai-data-entities/ai-reponses-to-user/ai-responses-to-user-repository.interface.js'; +import { AiChatMessageEntity } from '../../entities/ai/ai-conversation-history/ai-chat-messages/ai-chat-message.entity.js'; +import { IAiChatMessageRepository } from '../../entities/ai/ai-conversation-history/ai-chat-messages/repository/ai-chat-message-repository.interface.js'; +import { IUserAiChatRepository } from '../../entities/ai/ai-conversation-history/user-ai-chat/repository/user-ai-chat-repository.interface.js'; +import { UserAiChatEntity } from '../../entities/ai/ai-conversation-history/user-ai-chat/user-ai-chat.entity.js'; import { AiResponsesToUserEntity } from '../../entities/ai/ai-data-entities/ai-reponses-to-user/ai-responses-to-user.entity.js'; +import { IAiResponsesToUserRepository } from '../../entities/ai/ai-data-entities/ai-reponses-to-user/ai-responses-to-user-repository.interface.js'; import { UserApiKeyEntity } from '../../entities/api-key/api-key.entity.js'; import { IUserApiKeyRepository } from '../../entities/api-key/repository/user-api-key-repository.interface.js'; import { CompanyFaviconEntity } from '../../entities/company-favicon/company-favicon.entity.js'; @@ -11,20 +15,25 @@ import { IInvitationInCompanyRepository } from '../../entities/company-info/invi import { ICompanyInfoRepository } from '../../entities/company-info/repository/company-info-repository.interface.js'; import { CompanyLogoEntity } from '../../entities/company-logo/company-logo.entity.js'; import { CompanyTabTitleEntity } from '../../entities/company-tab-title/company-tab-title.entity.js'; -import { IConnectionPropertiesRepository } from '../../entities/connection-properties/repository/connection-properties.repository.interface.js'; import { ConnectionEntity } from '../../entities/connection/connection.entity.js'; import { IConnectionRepository } from '../../entities/connection/repository/connection.repository.interface.js'; +import { ConnectionPropertiesEntity } from '../../entities/connection-properties/connection-properties.entity.js'; +import { IConnectionPropertiesRepository } from '../../entities/connection-properties/repository/connection-properties.repository.interface.js'; import { ICustomFieldsRepository } from '../../entities/custom-field/repository/custom-fields-repository.interface.js'; import { IEmailVerificationRepository } from '../../entities/email/repository/email-verification.repository.interface.js'; import { IGroupRepository } from '../../entities/group/repository/group.repository.interface.js'; import { ILogOutRepository } from '../../entities/log-out/repository/log-out-repository.interface.js'; import { IPermissionRepository } from '../../entities/permission/repository/permission.repository.interface.js'; +import { ISecretAccessLogRepository } from '../../entities/secret-access-log/repository/secret-access-log-repository.interface.js'; +import { SecretAccessLogEntity } from '../../entities/secret-access-log/secret-access-log.entity.js'; import { ActionEventsEntity } from '../../entities/table-actions/table-action-events-module/action-event.entity.js'; import { IActionEventsRepository } from '../../entities/table-actions/table-action-events-module/repository/action-events-custom-repository.interface.js'; import { ActionRulesEntity } from '../../entities/table-actions/table-action-rules-module/action-rules.entity.js'; import { IActionRulesRepository } from '../../entities/table-actions/table-action-rules-module/repository/action-rules-custom-repository.interface.js'; import { ITableActionRepository } from '../../entities/table-actions/table-actions-module/repository/table-action-custom-repository.interface.js'; import { TableActionEntity } from '../../entities/table-actions/table-actions-module/table-action.entity.js'; +import { ITableCategoriesCustomRepository } from '../../entities/table-categories/repository/table-categories-repository.interface.js'; +import { TableCategoriesEntity } from '../../entities/table-categories/table-categories.entity.js'; import { TableFieldInfoEntity } from '../../entities/table-field-info/table-field-info.entity.js'; import { ITableFiltersCustomRepository } from '../../entities/table-filters/repository/table-filters-custom-repository.interface.js'; import { TableFiltersEntity } from '../../entities/table-filters/table-filters.entity.js'; @@ -32,40 +41,31 @@ import { TableInfoEntity } from '../../entities/table-info/table-info.entity.js' import { ITableLogsRepository } from '../../entities/table-logs/repository/table-logs-repository.interface.js'; import { ITableSettingsRepository } from '../../entities/table-settings/common-table-settings/repository/table-settings.repository.interface.js'; import { TableSettingsEntity } from '../../entities/table-settings/common-table-settings/table-settings.entity.js'; -import { IUserAccessRepository } from '../../entities/user-access/repository/user-access.repository.interface.js'; -import { IUserActionRepository } from '../../entities/user-actions/repository/user-action.repository.interface.js'; +import { PersonalTableSettingsEntity } from '../../entities/table-settings/personal-table-settings/personal-table-settings.entity.js'; +import { IPersonalTableSettingsRepository } from '../../entities/table-settings/personal-table-settings/repository/personal-table-settings.repository.interface.js'; import { IUserRepository } from '../../entities/user/repository/user.repository.interface.js'; +import { UserEntity } from '../../entities/user/user.entity.js'; import { IEmailChangeRepository } from '../../entities/user/user-email/repository/email-change.repository.interface.js'; import { IUserGitHubIdentifierRepository } from '../../entities/user/user-github-identifier/repository/user-github-identifier-repository.interface.js'; import { IUserInvitationRepository } from '../../entities/user/user-invitation/repository/user-invitation-repository.interface.js'; import { IPasswordResetRepository } from '../../entities/user/user-password/repository/password-reset-repository.interface.js'; import { IUserSessionSettings } from '../../entities/user/user-session-settings/reposiotory/user-session-settings-repository.interface.js'; import { UserSessionSettingsEntity } from '../../entities/user/user-session-settings/user-session-settings.entity.js'; -import { UserEntity } from '../../entities/user/user.entity.js'; -import { ITableWidgetsRepository } from '../../entities/widget/repository/table-widgets-repository.interface.js'; -import { TableWidgetEntity } from '../../entities/widget/table-widget.entity.js'; -import { IDatabaseContext } from '../database-context.interface.js'; -import { TableCategoriesEntity } from '../../entities/table-categories/table-categories.entity.js'; -import { ITableCategoriesCustomRepository } from '../../entities/table-categories/repository/table-categories-repository.interface.js'; -import { ConnectionPropertiesEntity } from '../../entities/connection-properties/connection-properties.entity.js'; -import { UserSecretEntity } from '../../entities/user-secret/user-secret.entity.js'; +import { IUserAccessRepository } from '../../entities/user-access/repository/user-access.repository.interface.js'; +import { IUserActionRepository } from '../../entities/user-actions/repository/user-action.repository.interface.js'; import { IUserSecretRepository } from '../../entities/user-secret/repository/user-secret-repository.interface.js'; -import { SecretAccessLogEntity } from '../../entities/secret-access-log/secret-access-log.entity.js'; -import { ISecretAccessLogRepository } from '../../entities/secret-access-log/repository/secret-access-log-repository.interface.js'; -import { SignInAuditEntity } from '../../entities/user-sign-in-audit/sign-in-audit.entity.js'; +import { UserSecretEntity } from '../../entities/user-secret/user-secret.entity.js'; import { ISignInAuditRepository } from '../../entities/user-sign-in-audit/repository/sign-in-audit-repository.interface.js'; -import { IPersonalTableSettingsRepository } from '../../entities/table-settings/personal-table-settings/repository/personal-table-settings.repository.interface.js'; -import { PersonalTableSettingsEntity } from '../../entities/table-settings/personal-table-settings/personal-table-settings.entity.js'; -import { SavedDbQueryEntity } from '../../entities/visualizations/saved-db-query/saved-db-query.entity.js'; -import { ISavedDbQueryRepository } from '../../entities/visualizations/saved-db-query/repository/saved-db-query.repository.interface.js'; +import { SignInAuditEntity } from '../../entities/user-sign-in-audit/sign-in-audit.entity.js'; import { DashboardEntity } from '../../entities/visualizations/dashboard/dashboard.entity.js'; -import { DashboardWidgetEntity } from '../../entities/visualizations/dashboard-widget/dashboard-widget.entity.js'; import { IDashboardRepository } from '../../entities/visualizations/dashboard/repository/dashboard.repository.interface.js'; +import { DashboardWidgetEntity } from '../../entities/visualizations/dashboard-widget/dashboard-widget.entity.js'; import { IDashboardWidgetRepository } from '../../entities/visualizations/dashboard-widget/repository/dashboard-widget.repository.interface.js'; -import { UserAiChatEntity } from '../../entities/ai/ai-conversation-history/user-ai-chat/user-ai-chat.entity.js'; -import { IUserAiChatRepository } from '../../entities/ai/ai-conversation-history/user-ai-chat/repository/user-ai-chat-repository.interface.js'; -import { AiChatMessageEntity } from '../../entities/ai/ai-conversation-history/ai-chat-messages/ai-chat-message.entity.js'; -import { IAiChatMessageRepository } from '../../entities/ai/ai-conversation-history/ai-chat-messages/repository/ai-chat-message-repository.interface.js'; +import { ISavedDbQueryRepository } from '../../entities/visualizations/saved-db-query/repository/saved-db-query.repository.interface.js'; +import { SavedDbQueryEntity } from '../../entities/visualizations/saved-db-query/saved-db-query.entity.js'; +import { ITableWidgetsRepository } from '../../entities/widget/repository/table-widgets-repository.interface.js'; +import { TableWidgetEntity } from '../../entities/widget/table-widget.entity.js'; +import { IDatabaseContext } from '../database-context.interface.js'; export interface IGlobalDatabaseContext extends IDatabaseContext { userRepository: Repository & IUserRepository; diff --git a/backend/src/common/application/global-database-context.ts b/backend/src/common/application/global-database-context.ts index 8da92c81e..286333140 100644 --- a/backend/src/common/application/global-database-context.ts +++ b/backend/src/common/application/global-database-context.ts @@ -3,120 +3,120 @@ import { DataSource, QueryRunner, Repository } from 'typeorm'; import { AgentEntity } from '../../entities/agent/agent.entity.js'; import { IAgentRepository } from '../../entities/agent/repository/agent.repository.interface.js'; import { customAgentRepositoryExtension } from '../../entities/agent/repository/custom-agent-repository-extension.js'; -import { ConnectionPropertiesEntity } from '../../entities/connection-properties/connection-properties.entity.js'; -import { IConnectionPropertiesRepository } from '../../entities/connection-properties/repository/connection-properties.repository.interface.js'; -import { customConnectionPropertiesRepositoryExtension } from '../../entities/connection-properties/repository/custom-connection-properties-repository-extension.js'; +import { AiChatMessageEntity } from '../../entities/ai/ai-conversation-history/ai-chat-messages/ai-chat-message.entity.js'; +import { aiChatMessageRepositoryExtension } from '../../entities/ai/ai-conversation-history/ai-chat-messages/repository/ai-chat-message-repository.extension.js'; +import { IAiChatMessageRepository } from '../../entities/ai/ai-conversation-history/ai-chat-messages/repository/ai-chat-message-repository.interface.js'; +import { userAiChatRepositoryExtension } from '../../entities/ai/ai-conversation-history/user-ai-chat/repository/user-ai-chat-repository.extension.js'; +import { IUserAiChatRepository } from '../../entities/ai/ai-conversation-history/user-ai-chat/repository/user-ai-chat-repository.interface.js'; +import { UserAiChatEntity } from '../../entities/ai/ai-conversation-history/user-ai-chat/user-ai-chat.entity.js'; +import { aiResponsesToUserRepositoryExtension } from '../../entities/ai/ai-data-entities/ai-reponses-to-user/ai-reponses-to-user-repository.extension.js'; +import { AiResponsesToUserEntity } from '../../entities/ai/ai-data-entities/ai-reponses-to-user/ai-responses-to-user.entity.js'; +import { IAiResponsesToUserRepository } from '../../entities/ai/ai-data-entities/ai-reponses-to-user/ai-responses-to-user-repository.interface.js'; +import { UserApiKeyEntity } from '../../entities/api-key/api-key.entity.js'; +import { userApiRepositoryExtension } from '../../entities/api-key/repository/user-api-key-repository.extension.js'; +import { IUserApiKeyRepository } from '../../entities/api-key/repository/user-api-key-repository.interface.js'; +import { CompanyFaviconEntity } from '../../entities/company-favicon/company-favicon.entity.js'; +import { CompanyInfoEntity } from '../../entities/company-info/company-info.entity.js'; +import { InvitationInCompanyEntity } from '../../entities/company-info/invitation-in-company/invitation-in-company.entity.js'; +import { invitationInCompanyCustomRepositoryExtension } from '../../entities/company-info/invitation-in-company/repository/invitation-in-company-custom-repository-extension.js'; +import { IInvitationInCompanyRepository } from '../../entities/company-info/invitation-in-company/repository/invitation-repository.interface.js'; +import { companyInfoRepositoryExtension } from '../../entities/company-info/repository/company-info-custom-repository.extension.js'; +import { ICompanyInfoRepository } from '../../entities/company-info/repository/company-info-repository.interface.js'; +import { CompanyLogoEntity } from '../../entities/company-logo/company-logo.entity.js'; +import { CompanyTabTitleEntity } from '../../entities/company-tab-title/company-tab-title.entity.js'; import { ConnectionEntity } from '../../entities/connection/connection.entity.js'; import { IConnectionRepository } from '../../entities/connection/repository/connection.repository.interface.js'; import { customConnectionRepositoryExtension } from '../../entities/connection/repository/custom-connection-repository-extension.js'; +import { ConnectionPropertiesEntity } from '../../entities/connection-properties/connection-properties.entity.js'; +import { IConnectionPropertiesRepository } from '../../entities/connection-properties/repository/connection-properties.repository.interface.js'; +import { customConnectionPropertiesRepositoryExtension } from '../../entities/connection-properties/repository/custom-connection-properties-repository-extension.js'; import { CustomFieldsEntity } from '../../entities/custom-field/custom-fields.entity.js'; import { cusomFieldsCustomRepositoryExtension } from '../../entities/custom-field/repository/custom-field-repository-extension.js'; import { ICustomFieldsRepository } from '../../entities/custom-field/repository/custom-fields-repository.interface.js'; import { EmailVerificationEntity } from '../../entities/email/email-verification.entity.js'; -import { emailVerificationRepositoryExtension } from '../../entities/email/repository/email-verification-custom-repository-extension.js'; import { IEmailVerificationRepository } from '../../entities/email/repository/email-verification.repository.interface.js'; +import { emailVerificationRepositoryExtension } from '../../entities/email/repository/email-verification-custom-repository-extension.js'; import { GroupEntity } from '../../entities/group/group.entity.js'; -import { groupCustomRepositoryExtension } from '../../entities/group/repository/group-custom-repository-extension.js'; import { IGroupRepository } from '../../entities/group/repository/group.repository.interface.js'; +import { groupCustomRepositoryExtension } from '../../entities/group/repository/group-custom-repository-extension.js'; import { LogOutEntity } from '../../entities/log-out/log-out.entity.js'; import { logOutCustomRepositoryExtension } from '../../entities/log-out/repository/log-out-custom-repository-extension.js'; import { ILogOutRepository } from '../../entities/log-out/repository/log-out-repository.interface.js'; import { PermissionEntity } from '../../entities/permission/permission.entity.js'; -import { permissionCustomRepositoryExtension } from '../../entities/permission/repository/permission-custom-repository-extension.js'; import { IPermissionRepository } from '../../entities/permission/repository/permission.repository.interface.js'; +import { permissionCustomRepositoryExtension } from '../../entities/permission/repository/permission-custom-repository-extension.js'; +import { secretAccessLogRepositoryExtension } from '../../entities/secret-access-log/repository/secret-access-log-repository.extension.js'; +import { ISecretAccessLogRepository } from '../../entities/secret-access-log/repository/secret-access-log-repository.interface.js'; +import { SecretAccessLogEntity } from '../../entities/secret-access-log/secret-access-log.entity.js'; +import { ActionEventsEntity } from '../../entities/table-actions/table-action-events-module/action-event.entity.js'; +import { actionEventsCustomRepositoryExtension } from '../../entities/table-actions/table-action-events-module/repository/action-events-custom-repository.extension.js'; +import { IActionEventsRepository } from '../../entities/table-actions/table-action-events-module/repository/action-events-custom-repository.interface.js'; +import { ActionRulesEntity } from '../../entities/table-actions/table-action-rules-module/action-rules.entity.js'; +import { IActionRulesRepository } from '../../entities/table-actions/table-action-rules-module/repository/action-rules-custom-repository.interface.js'; +import { actionRulesCustomRepositoryExtension } from '../../entities/table-actions/table-action-rules-module/repository/action-rules-custom-repository.js'; import { ITableActionRepository } from '../../entities/table-actions/table-actions-module/repository/table-action-custom-repository.interface.js'; import { tableActionsCustomRepositoryExtension } from '../../entities/table-actions/table-actions-module/repository/table-actions-custom-repository.extension.js'; import { TableActionEntity } from '../../entities/table-actions/table-actions-module/table-action.entity.js'; +import { tableCategoriesCustomRepositoryExtension } from '../../entities/table-categories/repository/table-categories-repository.extension.js'; +import { ITableCategoriesCustomRepository } from '../../entities/table-categories/repository/table-categories-repository.interface.js'; +import { TableCategoriesEntity } from '../../entities/table-categories/table-categories.entity.js'; import { TableFieldInfoEntity } from '../../entities/table-field-info/table-field-info.entity.js'; +import { ITableFiltersCustomRepository } from '../../entities/table-filters/repository/table-filters-custom-repository.interface.js'; +import { tableFiltersCustomRepositoryExtension } from '../../entities/table-filters/repository/table-filters-custom-repository-extension.js'; +import { TableFiltersEntity } from '../../entities/table-filters/table-filters.entity.js'; import { TableInfoEntity } from '../../entities/table-info/table-info.entity.js'; import { tableLogsCustomRepositoryExtension } from '../../entities/table-logs/repository/table-logs-custom-repository-extension.js'; import { ITableLogsRepository } from '../../entities/table-logs/repository/table-logs-repository.interface.js'; import { TableLogsEntity } from '../../entities/table-logs/table-logs.entity.js'; -import { tableSettingsCustomRepositoryExtension } from '../../entities/table-settings/common-table-settings/repository/table-settings-custom-repository-extension.js'; import { ITableSettingsRepository } from '../../entities/table-settings/common-table-settings/repository/table-settings.repository.interface.js'; +import { tableSettingsCustomRepositoryExtension } from '../../entities/table-settings/common-table-settings/repository/table-settings-custom-repository-extension.js'; import { TableSettingsEntity } from '../../entities/table-settings/common-table-settings/table-settings.entity.js'; -import { userAccessCustomReposiotoryExtension } from '../../entities/user-access/repository/user-access-custom-repository-extension.js'; -import { IUserAccessRepository } from '../../entities/user-access/repository/user-access.repository.interface.js'; -import { userActionCustomRepositoryExtension } from '../../entities/user-actions/repository/user-action-custom-repository-extension.js'; -import { IUserActionRepository } from '../../entities/user-actions/repository/user-action.repository.interface.js'; -import { UserActionEntity } from '../../entities/user-actions/user-action.entity.js'; -import { userCustomRepositoryExtension } from '../../entities/user/repository/user-custom-repository-extension.js'; +import { PersonalTableSettingsEntity } from '../../entities/table-settings/personal-table-settings/personal-table-settings.entity.js'; +import { IPersonalTableSettingsRepository } from '../../entities/table-settings/personal-table-settings/repository/personal-table-settings.repository.interface.js'; +import { personalTableSettingsCustomRepositoryExtension } from '../../entities/table-settings/personal-table-settings/repository/personal-table-settings-custom-repository-extension.js'; import { IUserRepository } from '../../entities/user/repository/user.repository.interface.js'; +import { userCustomRepositoryExtension } from '../../entities/user/repository/user-custom-repository-extension.js'; +import { UserEntity } from '../../entities/user/user.entity.js'; import { EmailChangeEntity } from '../../entities/user/user-email/email-change.entity.js'; -import { emailChangeCustomRepositoryExtension } from '../../entities/user/user-email/repository/email-change-custom-repository-extension.js'; import { IEmailChangeRepository } from '../../entities/user/user-email/repository/email-change.repository.interface.js'; +import { emailChangeCustomRepositoryExtension } from '../../entities/user/user-email/repository/email-change-custom-repository-extension.js'; +import { GitHubUserIdentifierEntity } from '../../entities/user/user-github-identifier/github-user-identifier.entity.js'; +import { userGitHubIdentifierCustomRepositoryExtension } from '../../entities/user/user-github-identifier/repository/user-github-identifier-custom-repository.extension.js'; +import { IUserGitHubIdentifierRepository } from '../../entities/user/user-github-identifier/repository/user-github-identifier-repository.interface.js'; import { userInvitationCustomRepositoryExtension } from '../../entities/user/user-invitation/repository/user-invitation-custom-repository-extension.js'; import { IUserInvitationRepository } from '../../entities/user/user-invitation/repository/user-invitation-repository.interface.js'; import { UserInvitationEntity } from '../../entities/user/user-invitation/user-invitation.entity.js'; import { PasswordResetEntity } from '../../entities/user/user-password/password-reset.entity.js'; import { IPasswordResetRepository } from '../../entities/user/user-password/repository/password-reset-repository.interface.js'; import { userPasswordResetCustomRepositoryExtension } from '../../entities/user/user-password/repository/user-password-custom-repository-extension.js'; -import { UserEntity } from '../../entities/user/user.entity.js'; -import { tableWidgetsCustomRepositoryExtension } from '../../entities/widget/repository/table-widgets-custom-repsitory-extension.js'; -import { ITableWidgetsRepository } from '../../entities/widget/repository/table-widgets-repository.interface.js'; -import { TableWidgetEntity } from '../../entities/widget/table-widget.entity.js'; -import { BaseType } from '../data-injection.tokens.js'; -import { IGlobalDatabaseContext } from './global-database-context.interface.js'; -import { IUserGitHubIdentifierRepository } from '../../entities/user/user-github-identifier/repository/user-github-identifier-repository.interface.js'; -import { GitHubUserIdentifierEntity } from '../../entities/user/user-github-identifier/github-user-identifier.entity.js'; -import { userGitHubIdentifierCustomRepositoryExtension } from '../../entities/user/user-github-identifier/repository/user-github-identifier-custom-repository.extension.js'; -import { ICompanyInfoRepository } from '../../entities/company-info/repository/company-info-repository.interface.js'; -import { CompanyInfoEntity } from '../../entities/company-info/company-info.entity.js'; -import { companyInfoRepositoryExtension } from '../../entities/company-info/repository/company-info-custom-repository.extension.js'; -import { InvitationInCompanyEntity } from '../../entities/company-info/invitation-in-company/invitation-in-company.entity.js'; -import { IInvitationInCompanyRepository } from '../../entities/company-info/invitation-in-company/repository/invitation-repository.interface.js'; -import { invitationInCompanyCustomRepositoryExtension } from '../../entities/company-info/invitation-in-company/repository/invitation-in-company-custom-repository-extension.js'; -import { UserSessionSettingsEntity } from '../../entities/user/user-session-settings/user-session-settings.entity.js'; import { userSessionSettingsRepositoryExtension } from '../../entities/user/user-session-settings/reposiotory/user-session-settings-custom-repository.extension.js'; import { IUserSessionSettings } from '../../entities/user/user-session-settings/reposiotory/user-session-settings-repository.interface.js'; -import { ActionRulesEntity } from '../../entities/table-actions/table-action-rules-module/action-rules.entity.js'; -import { IActionRulesRepository } from '../../entities/table-actions/table-action-rules-module/repository/action-rules-custom-repository.interface.js'; -import { actionRulesCustomRepositoryExtension } from '../../entities/table-actions/table-action-rules-module/repository/action-rules-custom-repository.js'; -import { ActionEventsEntity } from '../../entities/table-actions/table-action-events-module/action-event.entity.js'; -import { IActionEventsRepository } from '../../entities/table-actions/table-action-events-module/repository/action-events-custom-repository.interface.js'; -import { actionEventsCustomRepositoryExtension } from '../../entities/table-actions/table-action-events-module/repository/action-events-custom-repository.extension.js'; -import { IUserApiKeyRepository } from '../../entities/api-key/repository/user-api-key-repository.interface.js'; -import { UserApiKeyEntity } from '../../entities/api-key/api-key.entity.js'; -import { userApiRepositoryExtension } from '../../entities/api-key/repository/user-api-key-repository.extension.js'; -import { CompanyLogoEntity } from '../../entities/company-logo/company-logo.entity.js'; -import { CompanyFaviconEntity } from '../../entities/company-favicon/company-favicon.entity.js'; -import { CompanyTabTitleEntity } from '../../entities/company-tab-title/company-tab-title.entity.js'; -import { TableFiltersEntity } from '../../entities/table-filters/table-filters.entity.js'; -import { ITableFiltersCustomRepository } from '../../entities/table-filters/repository/table-filters-custom-repository.interface.js'; -import { tableFiltersCustomRepositoryExtension } from '../../entities/table-filters/repository/table-filters-custom-repository-extension.js'; -import { IAiResponsesToUserRepository } from '../../entities/ai/ai-data-entities/ai-reponses-to-user/ai-responses-to-user-repository.interface.js'; -import { AiResponsesToUserEntity } from '../../entities/ai/ai-data-entities/ai-reponses-to-user/ai-responses-to-user.entity.js'; -import { aiResponsesToUserRepositoryExtension } from '../../entities/ai/ai-data-entities/ai-reponses-to-user/ai-reponses-to-user-repository.extension.js'; -import { TableCategoriesEntity } from '../../entities/table-categories/table-categories.entity.js'; -import { ITableCategoriesCustomRepository } from '../../entities/table-categories/repository/table-categories-repository.interface.js'; -import { tableCategoriesCustomRepositoryExtension } from '../../entities/table-categories/repository/table-categories-repository.extension.js'; -import { UserSecretEntity } from '../../entities/user-secret/user-secret.entity.js'; -import { IUserSecretRepository } from '../../entities/user-secret/repository/user-secret-repository.interface.js'; +import { UserSessionSettingsEntity } from '../../entities/user/user-session-settings/user-session-settings.entity.js'; +import { IUserAccessRepository } from '../../entities/user-access/repository/user-access.repository.interface.js'; +import { userAccessCustomReposiotoryExtension } from '../../entities/user-access/repository/user-access-custom-repository-extension.js'; +import { IUserActionRepository } from '../../entities/user-actions/repository/user-action.repository.interface.js'; +import { userActionCustomRepositoryExtension } from '../../entities/user-actions/repository/user-action-custom-repository-extension.js'; +import { UserActionEntity } from '../../entities/user-actions/user-action.entity.js'; import { userSecretRepositoryExtension } from '../../entities/user-secret/repository/user-secret-repository.extension.js'; -import { SecretAccessLogEntity } from '../../entities/secret-access-log/secret-access-log.entity.js'; -import { ISecretAccessLogRepository } from '../../entities/secret-access-log/repository/secret-access-log-repository.interface.js'; -import { secretAccessLogRepositoryExtension } from '../../entities/secret-access-log/repository/secret-access-log-repository.extension.js'; -import { SignInAuditEntity } from '../../entities/user-sign-in-audit/sign-in-audit.entity.js'; -import { ISignInAuditRepository } from '../../entities/user-sign-in-audit/repository/sign-in-audit-repository.interface.js'; +import { IUserSecretRepository } from '../../entities/user-secret/repository/user-secret-repository.interface.js'; +import { UserSecretEntity } from '../../entities/user-secret/user-secret.entity.js'; import { signInAuditCustomRepositoryExtension } from '../../entities/user-sign-in-audit/repository/sign-in-audit-custom-repository-extension.js'; -import { PersonalTableSettingsEntity } from '../../entities/table-settings/personal-table-settings/personal-table-settings.entity.js'; -import { IPersonalTableSettingsRepository } from '../../entities/table-settings/personal-table-settings/repository/personal-table-settings.repository.interface.js'; -import { personalTableSettingsCustomRepositoryExtension } from '../../entities/table-settings/personal-table-settings/repository/personal-table-settings-custom-repository-extension.js'; -import { SavedDbQueryEntity } from '../../entities/visualizations/saved-db-query/saved-db-query.entity.js'; -import { ISavedDbQueryRepository } from '../../entities/visualizations/saved-db-query/repository/saved-db-query.repository.interface.js'; -import { savedDbQueryCustomRepositoryExtension } from '../../entities/visualizations/saved-db-query/repository/saved-db-query-custom-repository-extension.js'; +import { ISignInAuditRepository } from '../../entities/user-sign-in-audit/repository/sign-in-audit-repository.interface.js'; +import { SignInAuditEntity } from '../../entities/user-sign-in-audit/sign-in-audit.entity.js'; import { DashboardEntity } from '../../entities/visualizations/dashboard/dashboard.entity.js'; -import { DashboardWidgetEntity } from '../../entities/visualizations/dashboard-widget/dashboard-widget.entity.js'; import { IDashboardRepository } from '../../entities/visualizations/dashboard/repository/dashboard.repository.interface.js'; -import { IDashboardWidgetRepository } from '../../entities/visualizations/dashboard-widget/repository/dashboard-widget.repository.interface.js'; import { dashboardCustomRepositoryExtension } from '../../entities/visualizations/dashboard/repository/dashboard-custom-repository-extension.js'; +import { DashboardWidgetEntity } from '../../entities/visualizations/dashboard-widget/dashboard-widget.entity.js'; +import { IDashboardWidgetRepository } from '../../entities/visualizations/dashboard-widget/repository/dashboard-widget.repository.interface.js'; import { dashboardWidgetCustomRepositoryExtension } from '../../entities/visualizations/dashboard-widget/repository/dashboard-widget-custom-repository-extension.js'; -import { UserAiChatEntity } from '../../entities/ai/ai-conversation-history/user-ai-chat/user-ai-chat.entity.js'; -import { IUserAiChatRepository } from '../../entities/ai/ai-conversation-history/user-ai-chat/repository/user-ai-chat-repository.interface.js'; -import { userAiChatRepositoryExtension } from '../../entities/ai/ai-conversation-history/user-ai-chat/repository/user-ai-chat-repository.extension.js'; -import { AiChatMessageEntity } from '../../entities/ai/ai-conversation-history/ai-chat-messages/ai-chat-message.entity.js'; -import { IAiChatMessageRepository } from '../../entities/ai/ai-conversation-history/ai-chat-messages/repository/ai-chat-message-repository.interface.js'; -import { aiChatMessageRepositoryExtension } from '../../entities/ai/ai-conversation-history/ai-chat-messages/repository/ai-chat-message-repository.extension.js'; +import { ISavedDbQueryRepository } from '../../entities/visualizations/saved-db-query/repository/saved-db-query.repository.interface.js'; +import { savedDbQueryCustomRepositoryExtension } from '../../entities/visualizations/saved-db-query/repository/saved-db-query-custom-repository-extension.js'; +import { SavedDbQueryEntity } from '../../entities/visualizations/saved-db-query/saved-db-query.entity.js'; +import { tableWidgetsCustomRepositoryExtension } from '../../entities/widget/repository/table-widgets-custom-repsitory-extension.js'; +import { ITableWidgetsRepository } from '../../entities/widget/repository/table-widgets-repository.interface.js'; +import { TableWidgetEntity } from '../../entities/widget/table-widget.entity.js'; +import { BaseType } from '../data-injection.tokens.js'; +import { IGlobalDatabaseContext } from './global-database-context.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class GlobalDatabaseContext implements IGlobalDatabaseContext { diff --git a/backend/src/common/database-context.interface.ts b/backend/src/common/database-context.interface.ts index ecdaa3628..311df7970 100644 --- a/backend/src/common/database-context.interface.ts +++ b/backend/src/common/database-context.interface.ts @@ -1,9 +1,9 @@ export interface IDatabaseContext { - startTransaction(): Promise; + startTransaction(): Promise; - commitTransaction(): Promise; + commitTransaction(): Promise; - rollbackTransaction(): Promise; + rollbackTransaction(): Promise; - releaseQueryRunner(): Promise; + releaseQueryRunner(): Promise; } diff --git a/backend/src/decorators/body-email.decorator.ts b/backend/src/decorators/body-email.decorator.ts index 1575e3774..da3c473d8 100644 --- a/backend/src/decorators/body-email.decorator.ts +++ b/backend/src/decorators/body-email.decorator.ts @@ -1,18 +1,18 @@ import { BadRequestException, createParamDecorator, ExecutionContext } from '@nestjs/common'; import { IRequestWithCognitoInfo } from '../authorization/index.js'; import { Messages } from '../exceptions/text/messages.js'; -import { ValidationHelper } from '../helpers/validators/validation-helper.js'; import { isObjectPropertyExists } from '../helpers/validators/is-object-property-exists-validator.js'; +import { ValidationHelper } from '../helpers/validators/validation-helper.js'; export const BodyEmail = createParamDecorator((_data: any, ctx: ExecutionContext): string => { - const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest(); - const body = request.body; - if (isObjectPropertyExists(body, 'email')) { - const email = body.email; - if (ValidationHelper.isValidEmail(email)) { - return email; - } - throw new BadRequestException(Messages.EMAIL_SYNTAX_INVALID); - } - throw new BadRequestException(Messages.USER_EMAIL_MISSING); + const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest(); + const body = request.body; + if (isObjectPropertyExists(body, 'email')) { + const email = body.email; + if (ValidationHelper.isValidEmail(email)) { + return email; + } + throw new BadRequestException(Messages.EMAIL_SYNTAX_INVALID); + } + throw new BadRequestException(Messages.USER_EMAIL_MISSING); }); diff --git a/backend/src/decorators/body-uuid.decorator.ts b/backend/src/decorators/body-uuid.decorator.ts index 691b781a1..e2c8e911c 100644 --- a/backend/src/decorators/body-uuid.decorator.ts +++ b/backend/src/decorators/body-uuid.decorator.ts @@ -1,19 +1,19 @@ import { BadRequestException, createParamDecorator, ExecutionContext } from '@nestjs/common'; import { IRequestWithCognitoInfo } from '../authorization/index.js'; import { Messages } from '../exceptions/text/messages.js'; -import { ValidationHelper } from '../helpers/validators/validation-helper.js'; import { isObjectPropertyExists } from '../helpers/validators/is-object-property-exists-validator.js'; +import { ValidationHelper } from '../helpers/validators/validation-helper.js'; export const BodyUuid = createParamDecorator((paramName: string, ctx: ExecutionContext): string => { - const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest(); - const body = request.body; - if (isObjectPropertyExists(body, paramName)) { - // eslint-disable-next-line security/detect-object-injection - const uuId = body[paramName]; - if (ValidationHelper.isValidUUID(uuId) || ValidationHelper.isValidNanoId(uuId)) { - return uuId; - } - throw new BadRequestException(Messages.UUID_INVALID); - } - throw new BadRequestException(Messages.PARAMETER_NAME_MISSING(paramName)); + const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest(); + const body = request.body; + if (isObjectPropertyExists(body, paramName)) { + // eslint-disable-next-line security/detect-object-injection + const uuId = body[paramName]; + if (ValidationHelper.isValidUUID(uuId) || ValidationHelper.isValidNanoId(uuId)) { + return uuId; + } + throw new BadRequestException(Messages.UUID_INVALID); + } + throw new BadRequestException(Messages.PARAMETER_NAME_MISSING(paramName)); }); diff --git a/backend/src/decorators/gclid-decorator.ts b/backend/src/decorators/gclid-decorator.ts index abfab1807..14e3beefd 100644 --- a/backend/src/decorators/gclid-decorator.ts +++ b/backend/src/decorators/gclid-decorator.ts @@ -2,9 +2,9 @@ import { createParamDecorator, ExecutionContext } from '@nestjs/common'; import { IRequestWithCognitoInfo } from '../authorization/index.js'; export const GCLlId = createParamDecorator((_data: any, ctx: ExecutionContext): string => { - const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest(); - if (request.headers) { - return request.headers.gclid as string | undefined ?? null; - } - return null; + const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest(); + if (request.headers) { + return (request.headers.gclid as string | undefined) ?? null; + } + return null; }); diff --git a/backend/src/decorators/index.ts b/backend/src/decorators/index.ts index d1d8ea425..015d9f23c 100644 --- a/backend/src/decorators/index.ts +++ b/backend/src/decorators/index.ts @@ -1,10 +1,10 @@ -export { SlugUuid } from './slug-uuid.decorator.js'; -export { UserId } from './user-id.decorator.js'; +export { BodyEmail } from './body-email.decorator.js'; +export { BodyUuid } from './body-uuid.decorator.js'; export { GCLlId } from './gclid-decorator.js'; export { MasterPassword } from './master-password.decorator.js'; -export { VerificationString } from './slug-verification.decorator.js'; -export { BodyUuid } from './body-uuid.decorator.js'; -export { QueryUuid } from './query-uuid.decorator.js'; -export { BodyEmail } from './body-email.decorator.js'; export { QueryTableName } from './query-table-name.decorator.js'; -export { Timeout, TIMEOUT_KEY, TimeoutDefaults } from './timeout.decorator.js'; +export { QueryUuid } from './query-uuid.decorator.js'; +export { SlugUuid } from './slug-uuid.decorator.js'; +export { VerificationString } from './slug-verification.decorator.js'; +export { TIMEOUT_KEY, Timeout, TimeoutDefaults } from './timeout.decorator.js'; +export { UserId } from './user-id.decorator.js'; diff --git a/backend/src/decorators/master-password.decorator.ts b/backend/src/decorators/master-password.decorator.ts index 0660bef5d..51d0ff0c3 100644 --- a/backend/src/decorators/master-password.decorator.ts +++ b/backend/src/decorators/master-password.decorator.ts @@ -2,7 +2,7 @@ import { createParamDecorator, ExecutionContext } from '@nestjs/common'; import { IRequestWithCognitoInfo } from '../authorization/index.js'; export const MasterPassword = createParamDecorator((_data: any, ctx: ExecutionContext): string => { - const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest(); - const masterPwd = request.headers.masterpwd as string | undefined; - return masterPwd ? masterPwd : null; + const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest(); + const masterPwd = request.headers.masterpwd as string | undefined; + return masterPwd ? masterPwd : null; }); diff --git a/backend/src/decorators/query-table-name.decorator.ts b/backend/src/decorators/query-table-name.decorator.ts index 69c76f246..642f45990 100644 --- a/backend/src/decorators/query-table-name.decorator.ts +++ b/backend/src/decorators/query-table-name.decorator.ts @@ -4,10 +4,10 @@ import { Messages } from '../exceptions/text/messages.js'; import { isObjectPropertyExists } from '../helpers/validators/is-object-property-exists-validator.js'; export const QueryTableName = createParamDecorator((_data: unknown, ctx: ExecutionContext): string => { - const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest(); - const query = request.query; - if (isObjectPropertyExists(query, 'tableName') && query.tableName.length > 0) { - return query.tableName; - } - throw new BadRequestException(Messages.TABLE_NAME_MISSING); + const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest(); + const query = request.query; + if (isObjectPropertyExists(query, 'tableName') && query.tableName.length > 0) { + return query.tableName; + } + throw new BadRequestException(Messages.TABLE_NAME_MISSING); }); diff --git a/backend/src/decorators/query-uuid.decorator.ts b/backend/src/decorators/query-uuid.decorator.ts index 3f724d0ee..f49dc69d3 100644 --- a/backend/src/decorators/query-uuid.decorator.ts +++ b/backend/src/decorators/query-uuid.decorator.ts @@ -1,19 +1,19 @@ import { BadRequestException, createParamDecorator, ExecutionContext } from '@nestjs/common'; import { IRequestWithCognitoInfo } from '../authorization/index.js'; import { Messages } from '../exceptions/text/messages.js'; -import { ValidationHelper } from '../helpers/validators/validation-helper.js'; import { isObjectPropertyExists } from '../helpers/validators/is-object-property-exists-validator.js'; +import { ValidationHelper } from '../helpers/validators/validation-helper.js'; export const QueryUuid = createParamDecorator((paramName: string, ctx: ExecutionContext): string => { - const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest(); - const query = request.query; - if (isObjectPropertyExists(query, paramName)) { - // eslint-disable-next-line security/detect-object-injection - const uuId = query[paramName]; - if (ValidationHelper.isValidUUID(uuId) || ValidationHelper.isValidNanoId(uuId)) { - return uuId; - } - throw new BadRequestException(Messages.UUID_INVALID); - } - throw new BadRequestException(Messages.PARAMETER_NAME_MISSING(paramName)); + const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest(); + const query = request.query; + if (isObjectPropertyExists(query, paramName)) { + // eslint-disable-next-line security/detect-object-injection + const uuId = query[paramName]; + if (ValidationHelper.isValidUUID(uuId) || ValidationHelper.isValidNanoId(uuId)) { + return uuId; + } + throw new BadRequestException(Messages.UUID_INVALID); + } + throw new BadRequestException(Messages.PARAMETER_NAME_MISSING(paramName)); }); diff --git a/backend/src/decorators/slug-uuid.decorator.ts b/backend/src/decorators/slug-uuid.decorator.ts index fd6e2a925..9ad8450af 100644 --- a/backend/src/decorators/slug-uuid.decorator.ts +++ b/backend/src/decorators/slug-uuid.decorator.ts @@ -4,44 +4,44 @@ import { Messages } from '../exceptions/text/messages.js'; import { ValidationHelper } from '../helpers/validators/validation-helper.js'; export type SlugUuidParameter = - | 'slug' - | 'connectionId' - | 'groupId' - | 'userId' - | 'actionId' - | 'ruleId' - | 'eventId' - | 'apiKeyId' - | 'companyId' - | 'threadId' - | 'filterId' - | 'chatId'; + | 'slug' + | 'connectionId' + | 'groupId' + | 'userId' + | 'actionId' + | 'ruleId' + | 'eventId' + | 'apiKeyId' + | 'companyId' + | 'threadId' + | 'filterId' + | 'chatId'; export const SlugUuid = createParamDecorator( - (parameterName: SlugUuidParameter = 'slug', ctx: ExecutionContext): string => { - const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest(); - const availableSlagParameters: Array = [ - 'slug', - 'connectionId', - 'groupId', - 'userId', - 'apiKeyId', - 'actionId', - 'ruleId', - 'eventId', - 'companyId', - 'threadId', - 'filterId', - 'chatId' - ]; - if (!availableSlagParameters.includes(parameterName)) { - throw new BadRequestException(Messages.UUID_INVALID); - } - // eslint-disable-next-line security/detect-object-injection - const uuId: string = request.params?.[parameterName]; + (parameterName: SlugUuidParameter = 'slug', ctx: ExecutionContext): string => { + const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest(); + const availableSlagParameters: Array = [ + 'slug', + 'connectionId', + 'groupId', + 'userId', + 'apiKeyId', + 'actionId', + 'ruleId', + 'eventId', + 'companyId', + 'threadId', + 'filterId', + 'chatId', + ]; + if (!availableSlagParameters.includes(parameterName)) { + throw new BadRequestException(Messages.UUID_INVALID); + } + // eslint-disable-next-line security/detect-object-injection + const uuId: string = request.params?.[parameterName]; - if (ValidationHelper.isValidUUID(uuId) || ValidationHelper.isValidNanoId(uuId)) { - return uuId; - } - throw new BadRequestException(Messages.UUID_INVALID); - }, + if (ValidationHelper.isValidUUID(uuId) || ValidationHelper.isValidNanoId(uuId)) { + return uuId; + } + throw new BadRequestException(Messages.UUID_INVALID); + }, ); diff --git a/backend/src/decorators/slug-verification.decorator.ts b/backend/src/decorators/slug-verification.decorator.ts index b0fe18290..ccb8146e8 100644 --- a/backend/src/decorators/slug-verification.decorator.ts +++ b/backend/src/decorators/slug-verification.decorator.ts @@ -5,14 +5,14 @@ import { ValidationHelper } from '../helpers/validators/validation-helper.js'; type SlugVerificationType = 'verificationString'; export const VerificationString = createParamDecorator( - (paramName: SlugVerificationType, ctx: ExecutionContext): string => { - const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest(); - // eslint-disable-next-line security/detect-object-injection - const verificationString: string = request.params?.[paramName] || request.params?.slug; - const isValidString = ValidationHelper.isValidVerificationString(verificationString); - if (isValidString) { - return verificationString; - } - throw new BadRequestException(Messages.VERIFICATION_STRING_INCORRECT); - }, + (paramName: SlugVerificationType, ctx: ExecutionContext): string => { + const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest(); + // eslint-disable-next-line security/detect-object-injection + const verificationString: string = request.params?.[paramName] || request.params?.slug; + const isValidString = ValidationHelper.isValidVerificationString(verificationString); + if (isValidString) { + return verificationString; + } + throw new BadRequestException(Messages.VERIFICATION_STRING_INCORRECT); + }, ); diff --git a/backend/src/decorators/timeout.decorator.ts b/backend/src/decorators/timeout.decorator.ts index e4c0b1639..d68f2f058 100644 --- a/backend/src/decorators/timeout.decorator.ts +++ b/backend/src/decorators/timeout.decorator.ts @@ -1,4 +1,4 @@ -import { SetMetadata, applyDecorators, UseInterceptors } from '@nestjs/common'; +import { applyDecorators, SetMetadata, UseInterceptors } from '@nestjs/common'; import { TimeoutInterceptor } from '../interceptors/timeout.interceptor.js'; export const TIMEOUT_KEY = 'custom_timeout'; diff --git a/backend/src/decorators/user-id.decorator.ts b/backend/src/decorators/user-id.decorator.ts index 111786288..76ad1b4a7 100644 --- a/backend/src/decorators/user-id.decorator.ts +++ b/backend/src/decorators/user-id.decorator.ts @@ -4,13 +4,13 @@ import { Messages } from '../exceptions/text/messages.js'; import { ValidationHelper } from '../helpers/validators/validation-helper.js'; export const UserId = createParamDecorator((_data: any, ctx: ExecutionContext): string => { - const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest(); - const userId = request.decoded?.sub; - if (!userId) { - throw new BadRequestException(Messages.USER_ID_MISSING); - } - if (ValidationHelper.isValidUUID(userId)) { - return userId; - } - throw new BadRequestException(Messages.UUID_INVALID); + const request: IRequestWithCognitoInfo = ctx.switchToHttp().getRequest(); + const userId = request.decoded?.sub; + if (!userId) { + throw new BadRequestException(Messages.USER_ID_MISSING); + } + if (ValidationHelper.isValidUUID(userId)) { + return userId; + } + throw new BadRequestException(Messages.UUID_INVALID); }); diff --git a/backend/src/entities/agent/agent.entity.ts b/backend/src/entities/agent/agent.entity.ts index 166ed0e69..06b23c400 100644 --- a/backend/src/entities/agent/agent.entity.ts +++ b/backend/src/entities/agent/agent.entity.ts @@ -1,45 +1,48 @@ - import { - BeforeInsert, - BeforeUpdate, - Column, - Entity, - JoinColumn, - OneToOne, - PrimaryGeneratedColumn, - Relation, + BeforeInsert, + BeforeUpdate, + Column, + Entity, + JoinColumn, + OneToOne, + PrimaryGeneratedColumn, + Relation, } from 'typeorm'; -import { ConnectionEntity } from '../connection/connection.entity.js'; import { Encryptor } from '../../helpers/encryption/encryptor.js'; +import { ConnectionEntity } from '../connection/connection.entity.js'; @Entity('agent') export class AgentEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column() - token: string; + @Column() + token: string; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - createdAt: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + createdAt: Date; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - updatedAt: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + updatedAt: Date; - @BeforeInsert() - encryptToken(): void { - this.token = Encryptor.hashDataHMAC(this.token); - } + @BeforeInsert() + encryptToken(): void { + this.token = Encryptor.hashDataHMAC(this.token); + } - @BeforeUpdate() - updateTimestampAndEncryptToken(): void { - this.updatedAt = new Date(); - this.token = Encryptor.hashDataHMAC(this.token); - } + @BeforeUpdate() + updateTimestampAndEncryptToken(): void { + this.updatedAt = new Date(); + this.token = Encryptor.hashDataHMAC(this.token); + } - @OneToOne((_) => ConnectionEntity, (connection) => connection.agent, { - onDelete: 'CASCADE', - }) - @JoinColumn() - connection: Relation; + @OneToOne( + (_) => ConnectionEntity, + (connection) => connection.agent, + { + onDelete: 'CASCADE', + }, + ) + @JoinColumn() + connection: Relation; } diff --git a/backend/src/entities/agent/agent.module.ts b/backend/src/entities/agent/agent.module.ts index 019bb8267..c4fe7b780 100644 --- a/backend/src/entities/agent/agent.module.ts +++ b/backend/src/entities/agent/agent.module.ts @@ -8,17 +8,17 @@ import { UserEntity } from '../user/user.entity.js'; import { AgentEntity } from './agent.entity.js'; @Module({ - imports: [TypeOrmModule.forFeature([AgentEntity, UserEntity, LogOutEntity])], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - ], - exports: [], + imports: [TypeOrmModule.forFeature([AgentEntity, UserEntity, LogOutEntity])], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + ], + exports: [], }) export class AgentModule implements NestModule { - public configure(consumer: MiddlewareConsumer): any { - consumer.apply(AuthMiddleware).forRoutes(); - } + public configure(consumer: MiddlewareConsumer): any { + consumer.apply(AuthMiddleware).forRoutes(); + } } diff --git a/backend/src/entities/agent/repository/agent.repository.interface.ts b/backend/src/entities/agent/repository/agent.repository.interface.ts index 8255ae2fd..5a262133c 100644 --- a/backend/src/entities/agent/repository/agent.repository.interface.ts +++ b/backend/src/entities/agent/repository/agent.repository.interface.ts @@ -1,11 +1,10 @@ -import { AgentEntity } from '../agent.entity.js'; import { ConnectionEntity } from '../../connection/connection.entity.js'; +import { AgentEntity } from '../agent.entity.js'; export interface IAgentRepository { + createNewAgentForConnection(connection: ConnectionEntity): Promise; - createNewAgentForConnection(connection: ConnectionEntity): Promise; - - createNewAgentForConnectionAndReturnToken(connection: ConnectionEntity): Promise; + createNewAgentForConnectionAndReturnToken(connection: ConnectionEntity): Promise; - renewOrCreateConnectionToken(connectionId: string): Promise; + renewOrCreateConnectionToken(connectionId: string): Promise; } diff --git a/backend/src/entities/ai/ai-conversation-history/ai-chat-messages/ai-chat-message.entity.ts b/backend/src/entities/ai/ai-conversation-history/ai-chat-messages/ai-chat-message.entity.ts index ed31d9fef..44b6fb8a2 100644 --- a/backend/src/entities/ai/ai-conversation-history/ai-chat-messages/ai-chat-message.entity.ts +++ b/backend/src/entities/ai/ai-conversation-history/ai-chat-messages/ai-chat-message.entity.ts @@ -8,8 +8,8 @@ import { Relation, UpdateDateColumn, } from 'typeorm'; -import { MessageRole } from './message-role.enum.js'; import { UserAiChatEntity } from '../user-ai-chat/user-ai-chat.entity.js'; +import { MessageRole } from './message-role.enum.js'; @Entity('ai_chat_message') export class AiChatMessageEntity { diff --git a/backend/src/entities/ai/ai-conversation-history/ai-chat-messages/repository/ai-chat-message-repository.extension.ts b/backend/src/entities/ai/ai-conversation-history/ai-chat-messages/repository/ai-chat-message-repository.extension.ts index 535eec1cb..0e52bbd3c 100644 --- a/backend/src/entities/ai/ai-conversation-history/ai-chat-messages/repository/ai-chat-message-repository.extension.ts +++ b/backend/src/entities/ai/ai-conversation-history/ai-chat-messages/repository/ai-chat-message-repository.extension.ts @@ -1,6 +1,6 @@ -import { IAiChatMessageRepository } from './ai-chat-message-repository.interface.js'; import { AiChatMessageEntity } from '../ai-chat-message.entity.js'; import { MessageRole } from '../message-role.enum.js'; +import { IAiChatMessageRepository } from './ai-chat-message-repository.interface.js'; export const aiChatMessageRepositoryExtension: IAiChatMessageRepository = { async findMessagesForChat(chatId: string): Promise { diff --git a/backend/src/entities/ai/ai-conversation-history/user-ai-chat/repository/user-ai-chat-repository.extension.ts b/backend/src/entities/ai/ai-conversation-history/user-ai-chat/repository/user-ai-chat-repository.extension.ts index 5cfb32f34..28b9fe883 100644 --- a/backend/src/entities/ai/ai-conversation-history/user-ai-chat/repository/user-ai-chat-repository.extension.ts +++ b/backend/src/entities/ai/ai-conversation-history/user-ai-chat/repository/user-ai-chat-repository.extension.ts @@ -1,5 +1,5 @@ -import { IUserAiChatRepository } from './user-ai-chat-repository.interface.js'; import { UserAiChatEntity } from '../user-ai-chat.entity.js'; +import { IUserAiChatRepository } from './user-ai-chat-repository.interface.js'; export const userAiChatRepositoryExtension: IUserAiChatRepository = { async findAllChatsForUser(userId: string): Promise { @@ -34,10 +34,6 @@ export const userAiChatRepositoryExtension: IUserAiChatRepository = { }, async updateChatName(chatId: string, name: string): Promise { - await this.createQueryBuilder() - .update(UserAiChatEntity) - .set({ name }) - .where('id = :chatId', { chatId }) - .execute(); + await this.createQueryBuilder().update(UserAiChatEntity).set({ name }).where('id = :chatId', { chatId }).execute(); }, }; diff --git a/backend/src/entities/ai/ai-data-entities/ai-reponses-to-user/ai-reponses-to-user-repository.extension.ts b/backend/src/entities/ai/ai-data-entities/ai-reponses-to-user/ai-reponses-to-user-repository.extension.ts index 49168b56f..2d1bc8468 100644 --- a/backend/src/entities/ai/ai-data-entities/ai-reponses-to-user/ai-reponses-to-user-repository.extension.ts +++ b/backend/src/entities/ai/ai-data-entities/ai-reponses-to-user/ai-reponses-to-user-repository.extension.ts @@ -1,12 +1,12 @@ -import { IAiResponsesToUserRepository } from './ai-responses-to-user-repository.interface.js'; import { AiResponsesToUserEntity } from './ai-responses-to-user.entity.js'; +import { IAiResponsesToUserRepository } from './ai-responses-to-user-repository.interface.js'; export const aiResponsesToUserRepositoryExtension: IAiResponsesToUserRepository = { - async findResponseByIdAndUserId(responseId: string, userId: string): Promise { - return await this.createQueryBuilder('ai_responses_to_user') - .leftJoin('ai_responses_to_user.user', 'user') - .where('user.id = :userId', { userId }) - .andWhere('ai_responses_to_user.id = :responseId', { responseId }) - .getOne(); - }, + async findResponseByIdAndUserId(responseId: string, userId: string): Promise { + return await this.createQueryBuilder('ai_responses_to_user') + .leftJoin('ai_responses_to_user.user', 'user') + .where('user.id = :userId', { userId }) + .andWhere('ai_responses_to_user.id = :responseId', { responseId }) + .getOne(); + }, }; diff --git a/backend/src/entities/ai/ai-data-entities/ai-reponses-to-user/ai-responses-to-user-repository.interface.ts b/backend/src/entities/ai/ai-data-entities/ai-reponses-to-user/ai-responses-to-user-repository.interface.ts index 11836813b..5e4a5f1e8 100644 --- a/backend/src/entities/ai/ai-data-entities/ai-reponses-to-user/ai-responses-to-user-repository.interface.ts +++ b/backend/src/entities/ai/ai-data-entities/ai-reponses-to-user/ai-responses-to-user-repository.interface.ts @@ -1,5 +1,5 @@ import { AiResponsesToUserEntity } from './ai-responses-to-user.entity.js'; export interface IAiResponsesToUserRepository { - findResponseByIdAndUserId(responseId: string, userId: string): Promise; + findResponseByIdAndUserId(responseId: string, userId: string): Promise; } diff --git a/backend/src/entities/ai/ai-data-entities/ai-reponses-to-user/ai-responses-to-user.entity.ts b/backend/src/entities/ai/ai-data-entities/ai-reponses-to-user/ai-responses-to-user.entity.ts index f9531d092..24d4c7e8a 100644 --- a/backend/src/entities/ai/ai-data-entities/ai-reponses-to-user/ai-responses-to-user.entity.ts +++ b/backend/src/entities/ai/ai-data-entities/ai-reponses-to-user/ai-responses-to-user.entity.ts @@ -3,27 +3,31 @@ import { UserEntity } from '../../../user/user.entity.js'; @Entity('ai_responses_to_user') export class AiResponsesToUserEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ type: 'varchar', length: 128, nullable: true }) - ai_response_id: string; + @Column({ type: 'varchar', length: 128, nullable: true }) + ai_response_id: string; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - createdAt: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + createdAt: Date; - @Column({ type: 'timestamp', default: null, nullable: true }) - updatedAt: Date; + @Column({ type: 'timestamp', default: null, nullable: true }) + updatedAt: Date; - @Column() - user_id: string; + @Column() + user_id: string; - @ManyToOne((_) => UserEntity, (user) => user.ai_responses, { onDelete: 'CASCADE' }) - @JoinColumn({ name: 'user_id' }) - user: Relation; + @ManyToOne( + (_) => UserEntity, + (user) => user.ai_responses, + { onDelete: 'CASCADE' }, + ) + @JoinColumn({ name: 'user_id' }) + user: Relation; - @BeforeUpdate() - updateTimestamp() { - this.updatedAt = new Date(); - } + @BeforeUpdate() + updateTimestamp() { + this.updatedAt = new Date(); + } } diff --git a/backend/src/entities/ai/ai-data-entities/types/ai-module-types.ts b/backend/src/entities/ai/ai-data-entities/types/ai-module-types.ts index 7937e8748..c9a8019f0 100644 --- a/backend/src/entities/ai/ai-data-entities/types/ai-module-types.ts +++ b/backend/src/entities/ai/ai-data-entities/types/ai-module-types.ts @@ -1,6 +1,6 @@ -import { ForeignKeyDS } from "@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key.ds.js"; -import { PrimaryKeyDS } from "@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/primary-key.ds.js"; -import { TableStructureDS } from "@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/table-structure.ds.js"; +import { ForeignKeyDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key.ds.js'; +import { PrimaryKeyDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/primary-key.ds.js'; +import { TableStructureDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/table-structure.ds.js'; export type TableInformation = { table_name: string; diff --git a/backend/src/entities/ai/ai-use-cases.interface.ts b/backend/src/entities/ai/ai-use-cases.interface.ts index e4f6d084b..18ba3b42d 100644 --- a/backend/src/entities/ai/ai-use-cases.interface.ts +++ b/backend/src/entities/ai/ai-use-cases.interface.ts @@ -1,17 +1,11 @@ -import { InTransactionEnum } from "../../enums/in-transaction.enum.js"; -import { FindOneConnectionDs } from "../connection/application/data-structures/find-one-connection.ds.js"; -import { RequestInfoFromTableDSV2 } from "./application/data-structures/request-info-from-table.ds.js"; +import { InTransactionEnum } from '../../enums/in-transaction.enum.js'; +import { FindOneConnectionDs } from '../connection/application/data-structures/find-one-connection.ds.js'; +import { RequestInfoFromTableDSV2 } from './application/data-structures/request-info-from-table.ds.js'; export interface IRequestInfoFromTableV2 { - execute( - inputData: RequestInfoFromTableDSV2, - inTransaction: InTransactionEnum, - ): Promise; + execute(inputData: RequestInfoFromTableDSV2, inTransaction: InTransactionEnum): Promise; } export interface IAISettingsAndWidgetsCreation { - execute( - connectionData: FindOneConnectionDs, - inTransaction: InTransactionEnum, - ): Promise; + execute(connectionData: FindOneConnectionDs, inTransaction: InTransactionEnum): Promise; } diff --git a/backend/src/entities/ai/ai.module.ts b/backend/src/entities/ai/ai.module.ts index 97e6b1bd7..9ca85b5df 100644 --- a/backend/src/entities/ai/ai.module.ts +++ b/backend/src/entities/ai/ai.module.ts @@ -6,17 +6,17 @@ import { BaseType, UseCaseType } from '../../common/data-injection.tokens.js'; import { LogOutEntity } from '../log-out/log-out.entity.js'; import { UserEntity } from '../user/user.entity.js'; import { AiService } from './ai.service.js'; +import { AiChatMessageEntity } from './ai-conversation-history/ai-chat-messages/ai-chat-message.entity.js'; +import { DeleteUserAiChatUseCase } from './ai-conversation-history/use-cases/delete-user-ai-chat.use.case.js'; +import { FindUserAiChatByIdUseCase } from './ai-conversation-history/use-cases/find-user-ai-chat-by-id.use.case.js'; +import { FindUserAiChatsUseCase } from './ai-conversation-history/use-cases/find-user-ai-chats.use.case.js'; +import { UserAiChatEntity } from './ai-conversation-history/user-ai-chat/user-ai-chat.entity.js'; +import { UserAiChatController } from './ai-conversation-history/user-ai-chat.controller.js'; import { RequestAISettingsAndWidgetsCreationUseCase } from './use-cases/request-ai-settings-and-widgets-creation.use.case.js'; import { RequestInfoFromTableWithAIUseCaseV5 } from './use-cases/request-info-from-table-with-ai-v5.use.case.js'; import { RequestInfoFromTableWithAIUseCaseV6 } from './use-cases/request-info-from-table-with-ai-v6.use.case.js'; import { RequestInfoFromTableWithAIUseCaseV7 } from './use-cases/request-info-from-table-with-ai-v7.use.case.js'; import { UserAIRequestsControllerV2 } from './user-ai-requests-v2.controller.js'; -import { UserAiChatController } from './ai-conversation-history/user-ai-chat.controller.js'; -import { FindUserAiChatsUseCase } from './ai-conversation-history/use-cases/find-user-ai-chats.use.case.js'; -import { FindUserAiChatByIdUseCase } from './ai-conversation-history/use-cases/find-user-ai-chat-by-id.use.case.js'; -import { DeleteUserAiChatUseCase } from './ai-conversation-history/use-cases/delete-user-ai-chat.use.case.js'; -import { UserAiChatEntity } from './ai-conversation-history/user-ai-chat/user-ai-chat.entity.js'; -import { AiChatMessageEntity } from './ai-conversation-history/ai-chat-messages/ai-chat-message.entity.js'; @Global() @Module({ diff --git a/backend/src/entities/ai/application/data-structures/request-info-from-table.ds.ts b/backend/src/entities/ai/application/data-structures/request-info-from-table.ds.ts index 9bdb203d2..9fed99851 100644 --- a/backend/src/entities/ai/application/data-structures/request-info-from-table.ds.ts +++ b/backend/src/entities/ai/application/data-structures/request-info-from-table.ds.ts @@ -1,13 +1,14 @@ import { Response } from 'express'; + class RequestInfoFromTableDS { - connectionId: string; - tableName: string; - user_message: string; - user_id: string; - master_password: string; + connectionId: string; + tableName: string; + user_message: string; + user_id: string; + master_password: string; } export class RequestInfoFromTableDSV2 extends RequestInfoFromTableDS { - response: Response; - ai_thread_id?: string | null; + response: Response; + ai_thread_id?: string | null; } diff --git a/backend/src/entities/ai/application/dto/request-info-from-table-body.dto.ts b/backend/src/entities/ai/application/dto/request-info-from-table-body.dto.ts index f8b505de8..6579cf8d5 100644 --- a/backend/src/entities/ai/application/dto/request-info-from-table-body.dto.ts +++ b/backend/src/entities/ai/application/dto/request-info-from-table-body.dto.ts @@ -2,10 +2,10 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty, IsString, MaxLength, MinLength } from 'class-validator'; export class RequestInfoFromTableBodyDTO { - @ApiProperty() - @IsString() - @IsNotEmpty() - @MinLength(5) - @MaxLength(256) - user_message: string; + @ApiProperty() + @IsString() + @IsNotEmpty() + @MinLength(5) + @MaxLength(256) + user_message: string; } diff --git a/backend/src/entities/ai/use-cases/request-ai-settings-and-widgets-creation.use.case.ts b/backend/src/entities/ai/use-cases/request-ai-settings-and-widgets-creation.use.case.ts index 8826e600c..81bd06e0d 100644 --- a/backend/src/entities/ai/use-cases/request-ai-settings-and-widgets-creation.use.case.ts +++ b/backend/src/entities/ai/use-cases/request-ai-settings-and-widgets-creation.use.case.ts @@ -1,11 +1,11 @@ -import { BadRequestException, Inject, Injectable, Scope } from "@nestjs/common"; -import AbstractUseCase from "../../../common/abstract-use.case.js"; -import { IGlobalDatabaseContext } from "../../../common/application/global-database-context.interface.js"; -import { BaseType } from "../../../common/data-injection.tokens.js"; -import { Messages } from "../../../exceptions/text/messages.js"; -import { FindOneConnectionDs } from "../../connection/application/data-structures/find-one-connection.ds.js"; -import { SharedJobsService } from "../../shared-jobs/shared-jobs.service.js"; -import { IAISettingsAndWidgetsCreation } from "../ai-use-cases.interface.js"; +import { BadRequestException, Inject, Injectable, Scope } from '@nestjs/common'; +import AbstractUseCase from '../../../common/abstract-use.case.js'; +import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; +import { BaseType } from '../../../common/data-injection.tokens.js'; +import { Messages } from '../../../exceptions/text/messages.js'; +import { FindOneConnectionDs } from '../../connection/application/data-structures/find-one-connection.ds.js'; +import { SharedJobsService } from '../../shared-jobs/shared-jobs.service.js'; +import { IAISettingsAndWidgetsCreation } from '../ai-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class RequestAISettingsAndWidgetsCreationUseCase @@ -20,22 +20,14 @@ export class RequestAISettingsAndWidgetsCreationUseCase super(); } - public async implementation( - connectionData: FindOneConnectionDs, - ): Promise { + public async implementation(connectionData: FindOneConnectionDs): Promise { const { connectionId, masterPwd } = connectionData; - const connection = - await this._dbContext.connectionRepository.findAndDecryptConnection( - connectionId, - masterPwd, - ); + const connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, masterPwd); if (!connection) { throw new BadRequestException(Messages.CONNECTION_NOT_FOUND); } - await this.sharedJobsService.scanDatabaseAndCreateSettingsAndWidgetsWithAI( - connection, - ); + await this.sharedJobsService.scanDatabaseAndCreateSettingsAndWidgetsWithAI(connection); } } diff --git a/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v5.use.case.ts b/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v5.use.case.ts index a2d5a32fa..2e724f901 100644 --- a/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v5.use.case.ts +++ b/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v5.use.case.ts @@ -1,3 +1,4 @@ +import { BaseMessage } from '@langchain/core/messages'; import { BadRequestException, Inject, Injectable, NotFoundException, Scope } from '@nestjs/common'; import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; @@ -5,7 +6,17 @@ import { IDataAccessObject } from '@rocketadmin/shared-code/dist/src/shared/inte import { IDataAccessObjectAgent } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object-agent.interface.js'; import Sentry from '@sentry/minimal'; import { Response } from 'express'; -import { BaseMessage } from '@langchain/core/messages'; +import { + AICoreService, + AIToolCall, + AIToolDefinition, + createDatabaseQuerySystemPrompt, + createDatabaseTools, + isValidMongoDbCommand, + isValidSQLQuery, + MessageBuilder, + wrapQueryWithLimit, +} from '../../../ai-core/index.js'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; @@ -16,17 +27,6 @@ import { ConnectionEntity } from '../../connection/connection.entity.js'; import { AiResponsesToUserEntity } from '../ai-data-entities/ai-reponses-to-user/ai-responses-to-user.entity.js'; import { IRequestInfoFromTableV2 } from '../ai-use-cases.interface.js'; import { RequestInfoFromTableDSV2 } from '../application/data-structures/request-info-from-table.ds.js'; -import { - AICoreService, - AIToolDefinition, - AIToolCall, - MessageBuilder, - createDatabaseTools, - createDatabaseQuerySystemPrompt, - isValidSQLQuery, - isValidMongoDbCommand, - wrapQueryWithLimit, -} from '../../../ai-core/index.js'; @Injectable({ scope: Scope.REQUEST }) export class RequestInfoFromTableWithAIUseCaseV5 diff --git a/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v6.use.case.ts b/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v6.use.case.ts index 608148790..1bb01b63c 100644 --- a/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v6.use.case.ts +++ b/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v6.use.case.ts @@ -1,3 +1,4 @@ +import { BaseMessage } from '@langchain/core/messages'; import { BadRequestException, Inject, Injectable, NotFoundException, Scope } from '@nestjs/common'; import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; @@ -5,7 +6,18 @@ import { IDataAccessObject } from '@rocketadmin/shared-code/dist/src/shared/inte import { IDataAccessObjectAgent } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object-agent.interface.js'; import Sentry from '@sentry/minimal'; import { Response } from 'express'; -import { BaseMessage } from '@langchain/core/messages'; +import { + AICoreService, + AIProviderType, + AIToolCall, + AIToolDefinition, + createDatabaseQuerySystemPrompt, + createDatabaseTools, + isValidMongoDbCommand, + isValidSQLQuery, + MessageBuilder, + wrapQueryWithLimit, +} from '../../../ai-core/index.js'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; @@ -16,18 +28,6 @@ import { ConnectionEntity } from '../../connection/connection.entity.js'; import { AiResponsesToUserEntity } from '../ai-data-entities/ai-reponses-to-user/ai-responses-to-user.entity.js'; import { IRequestInfoFromTableV2 } from '../ai-use-cases.interface.js'; import { RequestInfoFromTableDSV2 } from '../application/data-structures/request-info-from-table.ds.js'; -import { - AICoreService, - AIToolDefinition, - AIToolCall, - MessageBuilder, - createDatabaseTools, - createDatabaseQuerySystemPrompt, - isValidSQLQuery, - isValidMongoDbCommand, - wrapQueryWithLimit, - AIProviderType, -} from '../../../ai-core/index.js'; @Injectable({ scope: Scope.REQUEST }) export class RequestInfoFromTableWithAIUseCaseV6 diff --git a/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v7.use.case.ts b/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v7.use.case.ts index 161f577c1..4d4d21e88 100644 --- a/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v7.use.case.ts +++ b/backend/src/entities/ai/use-cases/request-info-from-table-with-ai-v7.use.case.ts @@ -1,3 +1,4 @@ +import { BaseMessage } from '@langchain/core/messages'; import { BadRequestException, Inject, Injectable, NotFoundException, Scope } from '@nestjs/common'; import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; @@ -5,7 +6,19 @@ import { IDataAccessObject } from '@rocketadmin/shared-code/dist/src/shared/inte import { IDataAccessObjectAgent } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object-agent.interface.js'; import Sentry from '@sentry/minimal'; import { Response } from 'express'; -import { BaseMessage } from '@langchain/core/messages'; +import { + AICoreService, + AIProviderConfig, + AIProviderType, + AIToolCall, + AIToolDefinition, + createDatabaseQuerySystemPrompt, + createDatabaseTools, + isValidMongoDbCommand, + isValidSQLQuery, + MessageBuilder, + wrapQueryWithLimit, +} from '../../../ai-core/index.js'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; @@ -13,23 +26,10 @@ import { Messages } from '../../../exceptions/text/messages.js'; import { slackPostMessage } from '../../../helpers/index.js'; import { isConnectionTypeAgent } from '../../../helpers/is-connection-entity-agent.js'; import { ConnectionEntity } from '../../connection/connection.entity.js'; +import { MessageRole } from '../ai-conversation-history/ai-chat-messages/message-role.enum.js'; +import { UserAiChatEntity } from '../ai-conversation-history/user-ai-chat/user-ai-chat.entity.js'; import { IRequestInfoFromTableV2 } from '../ai-use-cases.interface.js'; import { RequestInfoFromTableDSV2 } from '../application/data-structures/request-info-from-table.ds.js'; -import { - AICoreService, - AIToolDefinition, - AIToolCall, - MessageBuilder, - createDatabaseTools, - createDatabaseQuerySystemPrompt, - isValidSQLQuery, - isValidMongoDbCommand, - wrapQueryWithLimit, - AIProviderType, - AIProviderConfig, -} from '../../../ai-core/index.js'; -import { UserAiChatEntity } from '../ai-conversation-history/user-ai-chat/user-ai-chat.entity.js'; -import { MessageRole } from '../ai-conversation-history/ai-chat-messages/message-role.enum.js'; @Injectable({ scope: Scope.REQUEST }) export class RequestInfoFromTableWithAIUseCaseV7 diff --git a/backend/src/entities/amplitude/amplitude.module.ts b/backend/src/entities/amplitude/amplitude.module.ts index 80b34cebf..46cf0bb74 100644 --- a/backend/src/entities/amplitude/amplitude.module.ts +++ b/backend/src/entities/amplitude/amplitude.module.ts @@ -5,8 +5,8 @@ import { AmplitudeService } from './amplitude.service.js'; @Global() @Module({ - imports: [TypeOrmModule.forFeature([UserEntity])], - providers: [AmplitudeService], - exports: [AmplitudeService], + imports: [TypeOrmModule.forFeature([UserEntity])], + providers: [AmplitudeService], + exports: [AmplitudeService], }) export class AmplitudeModule {} diff --git a/backend/src/entities/amplitude/amplitude.service.ts b/backend/src/entities/amplitude/amplitude.service.ts index b9c1c3582..b7901a3f4 100644 --- a/backend/src/entities/amplitude/amplitude.service.ts +++ b/backend/src/entities/amplitude/amplitude.service.ts @@ -7,59 +7,59 @@ import { UserEntity } from '../user/user.entity.js'; @Injectable() export class AmplitudeService { - constructor( - @InjectRepository(UserEntity) - private readonly userRepository: Repository, - ) {} + constructor( + @InjectRepository(UserEntity) + private readonly userRepository: Repository, + ) {} - public async formAndSendLogRecord(event_type: AmplitudeEventTypeEnum, user_id: string, options = null) { - try { - if (process.env.NODE_ENV === 'test') return; - let user_email = (await this.userRepository.findOne({ where: { id: user_id } }))?.email; - if (!user_email && options) { - user_email = options?.user_email; - } - let event_properties ; - if (user_email) { - event_properties = { - user_properties: { - email: user_email ? user_email : 'unknown', - tablesCount: options?.tablesCount ? options.tablesCount : undefined, - reason: options?.reason ? options?.reason : undefined, - message: options?.message ? options.message : undefined, - }, - }; - } - if (options?.operationCount && options?.operationCount > 0) { - const promisesArr = Array.from(Array(options.operationCount), () => - this.sendLog(event_type, user_id, event_properties), - ); - await Promise.allSettled(promisesArr); - return; - } - await this.sendLog(event_type, user_id, event_properties); - } catch (e) { - console.error('Failed to send log: ' + e); - } - } + public async formAndSendLogRecord(event_type: AmplitudeEventTypeEnum, user_id: string, options = null) { + try { + if (process.env.NODE_ENV === 'test') return; + let user_email = (await this.userRepository.findOne({ where: { id: user_id } }))?.email; + if (!user_email && options) { + user_email = options?.user_email; + } + let event_properties; + if (user_email) { + event_properties = { + user_properties: { + email: user_email ? user_email : 'unknown', + tablesCount: options?.tablesCount ? options.tablesCount : undefined, + reason: options?.reason ? options?.reason : undefined, + message: options?.message ? options.message : undefined, + }, + }; + } + if (options?.operationCount && options?.operationCount > 0) { + const promisesArr = Array.from(Array(options.operationCount), () => + this.sendLog(event_type, user_id, event_properties), + ); + await Promise.allSettled(promisesArr); + return; + } + await this.sendLog(event_type, user_id, event_properties); + } catch (e) { + console.error('Failed to send log: ' + e); + } + } - private async sendLog(eventType, cognitoUserName, eventProperties) { - const client = Amplitude.init(process.env.AMPLITUDE_API_KEY); - try { - client - .logEvent({ - event_type: eventType, - user_id: cognitoUserName, - event_properties: eventProperties ? eventProperties : undefined, - }) - .catch((e) => { - throw new Error(e); - }); - client.flush().catch((e) => { - throw new Error(e); - }); - } catch (e) { - console.error(e); - } - } + private async sendLog(eventType, cognitoUserName, eventProperties) { + const client = Amplitude.init(process.env.AMPLITUDE_API_KEY); + try { + client + .logEvent({ + event_type: eventType, + user_id: cognitoUserName, + event_properties: eventProperties ? eventProperties : undefined, + }) + .catch((e) => { + throw new Error(e); + }); + client.flush().catch((e) => { + throw new Error(e); + }); + } catch (e) { + console.error(e); + } + } } diff --git a/backend/src/entities/api-key/api-key.controller.ts b/backend/src/entities/api-key/api-key.controller.ts index 7d8a6c64a..500ca1c42 100644 --- a/backend/src/entities/api-key/api-key.controller.ts +++ b/backend/src/entities/api-key/api-key.controller.ts @@ -2,6 +2,7 @@ import { Body, Controller, Delete, Get, Inject, Injectable, Post, UseInterceptor import { ApiBearerAuth, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import { UseCaseType } from '../../common/data-injection.tokens.js'; import { SlugUuid } from '../../decorators/slug-uuid.decorator.js'; +import { Timeout } from '../../decorators/timeout.decorator.js'; import { UserId } from '../../decorators/user-id.decorator.js'; import { InTransactionEnum } from '../../enums/in-transaction.enum.js'; import { SentryInterceptor } from '../../interceptors/sentry.interceptor.js'; @@ -11,7 +12,6 @@ import { FoundApiKeyDto } from './application/dto/found-api-key.dto.js'; import { ICreateApiKey, IDeleteApiKey, IGetApiKey, IGetApiKeys } from './use-cases/api-key-use-cases.interface.js'; import { buildCreatedApiKeyDto } from './utils/build-created-api-key.dto.js'; import { buildFoundApiKeyDto } from './utils/build-found-api-key.dto.js'; -import { Timeout } from '../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/api-key/api-key.entity.ts b/backend/src/entities/api-key/api-key.entity.ts index 259152ee8..fffb19b27 100644 --- a/backend/src/entities/api-key/api-key.entity.ts +++ b/backend/src/entities/api-key/api-key.entity.ts @@ -1,29 +1,33 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import { BeforeInsert, Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn, Relation } from 'typeorm'; -import { UserEntity } from '../user/user.entity.js'; -import { Encryptor } from '../../helpers/encryption/encryptor.js'; import { EncryptionAlgorithmEnum } from '../../enums/encryption-algorithm.enum.js'; +import { Encryptor } from '../../helpers/encryption/encryptor.js'; +import { UserEntity } from '../user/user.entity.js'; @Entity('user_api_key') export class UserApiKeyEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ type: 'varchar', length: 255, unique: false, nullable: false }) - title: string; + @Column({ type: 'varchar', length: 255, unique: false, nullable: false }) + title: string; - @Column({ type: 'varchar', unique: true, nullable: false }) - hash: string; + @Column({ type: 'varchar', unique: true, nullable: false }) + hash: string; - @ManyToOne((_type) => UserEntity, (user) => user.api_keys, { onDelete: 'CASCADE' }) - @JoinColumn() - user: Relation; + @ManyToOne( + (_type) => UserEntity, + (user) => user.api_keys, + { onDelete: 'CASCADE' }, + ) + @JoinColumn() + user: Relation; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - created_at: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + created_at: Date; - @BeforeInsert() - async generateHash() { - this.hash = await Encryptor.processDataWithAlgorithm(this.hash, EncryptionAlgorithmEnum.sha256); - } + @BeforeInsert() + async generateHash() { + this.hash = await Encryptor.processDataWithAlgorithm(this.hash, EncryptionAlgorithmEnum.sha256); + } } diff --git a/backend/src/entities/api-key/api-key.module.ts b/backend/src/entities/api-key/api-key.module.ts index fef8ef968..36fb2631b 100644 --- a/backend/src/entities/api-key/api-key.module.ts +++ b/backend/src/entities/api-key/api-key.module.ts @@ -1,56 +1,56 @@ import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common'; -import { ApiKeyController } from './api-key.controller.js'; -import { AuthMiddleware } from '../../authorization/auth.middleware.js'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { UserApiKeyEntity } from './api-key.entity.js'; +import { AuthMiddleware } from '../../authorization/auth.middleware.js'; +import { AuthWithApiMiddleware } from '../../authorization/auth-with-api.middleware.js'; import { GlobalDatabaseContext } from '../../common/application/global-database-context.js'; import { BaseType, UseCaseType } from '../../common/data-injection.tokens.js'; -import { CreateApiKeyUseCase } from './use-cases/create-api-key.use.case.js'; -import { UserEntity } from '../user/user.entity.js'; import { LogOutEntity } from '../log-out/log-out.entity.js'; +import { UserEntity } from '../user/user.entity.js'; +import { ApiKeyController } from './api-key.controller.js'; +import { UserApiKeyEntity } from './api-key.entity.js'; +import { CreateApiKeyUseCase } from './use-cases/create-api-key.use.case.js'; +import { DeleteApiKeyUseCase } from './use-cases/delete-api-key.use.case.js'; import { GetAllUserApiKeysUseCase } from './use-cases/get-all-user-api-keys.use.case.js'; import { GetUserApiKeyUseCase } from './use-cases/get-user-api-key.use.case.js'; -import { DeleteApiKeyUseCase } from './use-cases/delete-api-key.use.case.js'; -import { AuthWithApiMiddleware } from '../../authorization/auth-with-api.middleware.js'; @Module({ - imports: [TypeOrmModule.forFeature([UserApiKeyEntity, UserEntity, LogOutEntity])], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.CREATE_API_KEY, - useClass: CreateApiKeyUseCase, - }, - { - provide: UseCaseType.GET_API_KEYS, - useClass: GetAllUserApiKeysUseCase, - }, - { - provide: UseCaseType.GET_API_KEY, - useClass: GetUserApiKeyUseCase, - }, - { - provide: UseCaseType.DELETE_API_KEY, - useClass: DeleteApiKeyUseCase, - }, - ], - controllers: [ApiKeyController], + imports: [TypeOrmModule.forFeature([UserApiKeyEntity, UserEntity, LogOutEntity])], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.CREATE_API_KEY, + useClass: CreateApiKeyUseCase, + }, + { + provide: UseCaseType.GET_API_KEYS, + useClass: GetAllUserApiKeysUseCase, + }, + { + provide: UseCaseType.GET_API_KEY, + useClass: GetUserApiKeyUseCase, + }, + { + provide: UseCaseType.DELETE_API_KEY, + useClass: DeleteApiKeyUseCase, + }, + ], + controllers: [ApiKeyController], }) export class ApiKeyModule implements NestModule { - public configure(consumer: MiddlewareConsumer): any { - consumer - .apply(AuthMiddleware) - .forRoutes( - { path: '/apikey', method: RequestMethod.POST }, - { path: '/apikey/:apiKeyId', method: RequestMethod.DELETE }, - { path: '/apikey', method: RequestMethod.PUT }, - { path: '/apikeys', method: RequestMethod.GET }, - { path: '/apikey/:apiKeyId', method: RequestMethod.GET }, - ) - .apply(AuthWithApiMiddleware) - .forRoutes({ path: '/check/apikey', method: RequestMethod.GET }); - } + public configure(consumer: MiddlewareConsumer): any { + consumer + .apply(AuthMiddleware) + .forRoutes( + { path: '/apikey', method: RequestMethod.POST }, + { path: '/apikey/:apiKeyId', method: RequestMethod.DELETE }, + { path: '/apikey', method: RequestMethod.PUT }, + { path: '/apikeys', method: RequestMethod.GET }, + { path: '/apikey/:apiKeyId', method: RequestMethod.GET }, + ) + .apply(AuthWithApiMiddleware) + .forRoutes({ path: '/check/apikey', method: RequestMethod.GET }); + } } diff --git a/backend/src/entities/api-key/application/data-structures/create-api-key.ds.ts b/backend/src/entities/api-key/application/data-structures/create-api-key.ds.ts index 3eca76057..f84e68bbf 100644 --- a/backend/src/entities/api-key/application/data-structures/create-api-key.ds.ts +++ b/backend/src/entities/api-key/application/data-structures/create-api-key.ds.ts @@ -1,4 +1,4 @@ export class CreateApiKeyDS { - title: string; - userId: string; -} \ No newline at end of file + title: string; + userId: string; +} diff --git a/backend/src/entities/api-key/application/data-structures/created-api-key.ds.ts b/backend/src/entities/api-key/application/data-structures/created-api-key.ds.ts index ed086671f..e2616c700 100644 --- a/backend/src/entities/api-key/application/data-structures/created-api-key.ds.ts +++ b/backend/src/entities/api-key/application/data-structures/created-api-key.ds.ts @@ -1,6 +1,6 @@ export class CreatedApiKeyDS { - id: string; - title: string; - hash: string; - created_at: Date; + id: string; + title: string; + hash: string; + created_at: Date; } diff --git a/backend/src/entities/api-key/application/data-structures/find-api-key.ds.ts b/backend/src/entities/api-key/application/data-structures/find-api-key.ds.ts index 522b86476..04100cba1 100644 --- a/backend/src/entities/api-key/application/data-structures/find-api-key.ds.ts +++ b/backend/src/entities/api-key/application/data-structures/find-api-key.ds.ts @@ -1,4 +1,4 @@ export class FindApiKeyDS { - userId: string; - apiKeyId: string; -} \ No newline at end of file + userId: string; + apiKeyId: string; +} diff --git a/backend/src/entities/api-key/application/dto/create-api-key.dto.ts b/backend/src/entities/api-key/application/dto/create-api-key.dto.ts index eaeb94250..60133ea9a 100644 --- a/backend/src/entities/api-key/application/dto/create-api-key.dto.ts +++ b/backend/src/entities/api-key/application/dto/create-api-key.dto.ts @@ -2,9 +2,9 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty, IsString, MinLength } from 'class-validator'; export class CreateApiKeyDto { - @ApiProperty() - @IsString() - @IsNotEmpty() - @MinLength(1) - title: string; + @ApiProperty() + @IsString() + @IsNotEmpty() + @MinLength(1) + title: string; } diff --git a/backend/src/entities/api-key/application/dto/created-api-key.dto.ts b/backend/src/entities/api-key/application/dto/created-api-key.dto.ts index afd71d9b8..19647a623 100644 --- a/backend/src/entities/api-key/application/dto/created-api-key.dto.ts +++ b/backend/src/entities/api-key/application/dto/created-api-key.dto.ts @@ -1,15 +1,15 @@ import { ApiProperty } from '@nestjs/swagger'; export class CreatedApiKeyDto { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - title: string; + @ApiProperty() + title: string; - @ApiProperty() - hash: string; + @ApiProperty() + hash: string; - @ApiProperty() - created_at: Date; + @ApiProperty() + created_at: Date; } diff --git a/backend/src/entities/api-key/application/dto/found-api-key.ds.ts b/backend/src/entities/api-key/application/dto/found-api-key.ds.ts index 09615a0b2..cf44393ee 100644 --- a/backend/src/entities/api-key/application/dto/found-api-key.ds.ts +++ b/backend/src/entities/api-key/application/dto/found-api-key.ds.ts @@ -1,5 +1,5 @@ export class FoundApiKeyDS { - id: string; - title: string; - created_at: Date; + id: string; + title: string; + created_at: Date; } diff --git a/backend/src/entities/api-key/application/dto/found-api-key.dto.ts b/backend/src/entities/api-key/application/dto/found-api-key.dto.ts index 4b6680774..bd034b8ec 100644 --- a/backend/src/entities/api-key/application/dto/found-api-key.dto.ts +++ b/backend/src/entities/api-key/application/dto/found-api-key.dto.ts @@ -1,9 +1,9 @@ import { ApiProperty } from '@nestjs/swagger'; export class FoundApiKeyDto { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - title: string; + @ApiProperty() + title: string; } diff --git a/backend/src/entities/api-key/repository/user-api-key-repository.extension.ts b/backend/src/entities/api-key/repository/user-api-key-repository.extension.ts index ac537daed..5a0e6e6fb 100644 --- a/backend/src/entities/api-key/repository/user-api-key-repository.extension.ts +++ b/backend/src/entities/api-key/repository/user-api-key-repository.extension.ts @@ -2,18 +2,18 @@ import { UserApiKeyEntity } from '../api-key.entity.js'; import { IUserApiKeyRepository } from './user-api-key-repository.interface.js'; export const userApiRepositoryExtension: IUserApiKeyRepository = { - async findApiKeysByUserId(userId: string): Promise> { - return await this.createQueryBuilder('user_api_key') - .leftJoinAndSelect('user_api_key.user', 'user') - .where('user.id = :userId', { userId }) - .getMany(); - }, + async findApiKeysByUserId(userId: string): Promise> { + return await this.createQueryBuilder('user_api_key') + .leftJoinAndSelect('user_api_key.user', 'user') + .where('user.id = :userId', { userId }) + .getMany(); + }, - async findApiKeyByIdAndUserId(apiKeyId: string, userId: string): Promise { - return await this.createQueryBuilder('user_api_key') - .leftJoinAndSelect('user_api_key.user', 'user') - .where('user.id = :userId', { userId }) - .andWhere('user_api_key.id = :apiKeyId', { apiKeyId }) - .getOne(); - }, + async findApiKeyByIdAndUserId(apiKeyId: string, userId: string): Promise { + return await this.createQueryBuilder('user_api_key') + .leftJoinAndSelect('user_api_key.user', 'user') + .where('user.id = :userId', { userId }) + .andWhere('user_api_key.id = :apiKeyId', { apiKeyId }) + .getOne(); + }, }; diff --git a/backend/src/entities/api-key/repository/user-api-key-repository.interface.ts b/backend/src/entities/api-key/repository/user-api-key-repository.interface.ts index cc501ac2e..11dd00c64 100644 --- a/backend/src/entities/api-key/repository/user-api-key-repository.interface.ts +++ b/backend/src/entities/api-key/repository/user-api-key-repository.interface.ts @@ -1,7 +1,7 @@ import { UserApiKeyEntity } from '../api-key.entity.js'; export interface IUserApiKeyRepository { - findApiKeysByUserId(userId: string): Promise>; + findApiKeysByUserId(userId: string): Promise>; - findApiKeyByIdAndUserId(apiKeyId: string, userId: string): Promise; + findApiKeyByIdAndUserId(apiKeyId: string, userId: string): Promise; } diff --git a/backend/src/entities/api-key/use-cases/api-key-use-cases.interface.ts b/backend/src/entities/api-key/use-cases/api-key-use-cases.interface.ts index 1a8daa8b4..25c6fcb85 100644 --- a/backend/src/entities/api-key/use-cases/api-key-use-cases.interface.ts +++ b/backend/src/entities/api-key/use-cases/api-key-use-cases.interface.ts @@ -5,17 +5,17 @@ import { FindApiKeyDS } from '../application/data-structures/find-api-key.ds.js' import { FoundApiKeyDS } from '../application/dto/found-api-key.ds.js'; export interface ICreateApiKey { - execute(inputData: CreateApiKeyDS, inTransaction: InTransactionEnum): Promise; + execute(inputData: CreateApiKeyDS, inTransaction: InTransactionEnum): Promise; } export interface IGetApiKeys { - execute(userId: string): Promise>; + execute(userId: string): Promise>; } export interface IGetApiKey { - execute(apiKeyData: FindApiKeyDS): Promise; + execute(apiKeyData: FindApiKeyDS): Promise; } export interface IDeleteApiKey { - execute(apiKeyData: FindApiKeyDS, inTransaction: InTransactionEnum): Promise; + execute(apiKeyData: FindApiKeyDS, inTransaction: InTransactionEnum): Promise; } diff --git a/backend/src/entities/api-key/use-cases/create-api-key.use.case.ts b/backend/src/entities/api-key/use-cases/create-api-key.use.case.ts index d2e8ea78a..c5c62976f 100644 --- a/backend/src/entities/api-key/use-cases/create-api-key.use.case.ts +++ b/backend/src/entities/api-key/use-cases/create-api-key.use.case.ts @@ -1,34 +1,34 @@ import { Inject, Injectable, NotFoundException, Scope } from '@nestjs/common'; -import { CreateApiKeyDS } from '../application/data-structures/create-api-key.ds.js'; -import { CreatedApiKeyDS } from '../application/data-structures/created-api-key.ds.js'; -import { ICreateApiKey } from './api-key-use-cases.interface.js'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { BaseType } from '../../../common/data-injection.tokens.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; +import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; -import { buildNewApiKeyEntity } from '../utils/build-new-api-key-entity.js'; +import { CreateApiKeyDS } from '../application/data-structures/create-api-key.ds.js'; +import { CreatedApiKeyDS } from '../application/data-structures/created-api-key.ds.js'; import { buildCreatedApiKeyDS } from '../utils/build-created-api-key-ds.js'; +import { buildNewApiKeyEntity } from '../utils/build-new-api-key-entity.js'; +import { ICreateApiKey } from './api-key-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class CreateApiKeyUseCase extends AbstractUseCase implements ICreateApiKey { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: CreateApiKeyDS): Promise { - const { userId } = inputData; - const foundUser = await this._dbContext.userRepository.findOneUserById(userId); - if (!foundUser) { - throw new NotFoundException(Messages.USER_NOT_FOUND); - } - const newApiKey = buildNewApiKeyEntity(inputData); - newApiKey.user = foundUser; - const hashOriginal = newApiKey.hash; - const createdApiKey = await this._dbContext.userApiKeysRepository.save(newApiKey); - createdApiKey.hash = hashOriginal; - return buildCreatedApiKeyDS(createdApiKey); - } + protected async implementation(inputData: CreateApiKeyDS): Promise { + const { userId } = inputData; + const foundUser = await this._dbContext.userRepository.findOneUserById(userId); + if (!foundUser) { + throw new NotFoundException(Messages.USER_NOT_FOUND); + } + const newApiKey = buildNewApiKeyEntity(inputData); + newApiKey.user = foundUser; + const hashOriginal = newApiKey.hash; + const createdApiKey = await this._dbContext.userApiKeysRepository.save(newApiKey); + createdApiKey.hash = hashOriginal; + return buildCreatedApiKeyDS(createdApiKey); + } } diff --git a/backend/src/entities/api-key/use-cases/delete-api-key.use.case.ts b/backend/src/entities/api-key/use-cases/delete-api-key.use.case.ts index 62d05d194..e0e6196e8 100644 --- a/backend/src/entities/api-key/use-cases/delete-api-key.use.case.ts +++ b/backend/src/entities/api-key/use-cases/delete-api-key.use.case.ts @@ -1,30 +1,30 @@ import { Inject, Injectable, NotFoundException, Scope } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { IDeleteApiKey } from './api-key-use-cases.interface.js'; -import { FoundApiKeyDS } from '../application/dto/found-api-key.ds.js'; -import { FindApiKeyDS } from '../application/data-structures/find-api-key.ds.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { FindApiKeyDS } from '../application/data-structures/find-api-key.ds.js'; +import { FoundApiKeyDS } from '../application/dto/found-api-key.ds.js'; import { buildFoundApiKeyDS } from '../utils/build-found-api-key.ds.js'; +import { IDeleteApiKey } from './api-key-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class DeleteApiKeyUseCase extends AbstractUseCase implements IDeleteApiKey { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - public async implementation(apiKeyData: FindApiKeyDS): Promise { - const { apiKeyId, userId } = apiKeyData; - const foundApiKey = await this._dbContext.userApiKeysRepository.findApiKeyByIdAndUserId(apiKeyId, userId); - if (!foundApiKey) { - throw new NotFoundException(Messages.API_KEY_NOT_FOUND); - } - const foundApiKeyCopy = Object.assign({}, foundApiKey); - await this._dbContext.userApiKeysRepository.remove(foundApiKey); - return buildFoundApiKeyDS(foundApiKeyCopy); - } + public async implementation(apiKeyData: FindApiKeyDS): Promise { + const { apiKeyId, userId } = apiKeyData; + const foundApiKey = await this._dbContext.userApiKeysRepository.findApiKeyByIdAndUserId(apiKeyId, userId); + if (!foundApiKey) { + throw new NotFoundException(Messages.API_KEY_NOT_FOUND); + } + const foundApiKeyCopy = Object.assign({}, foundApiKey); + await this._dbContext.userApiKeysRepository.remove(foundApiKey); + return buildFoundApiKeyDS(foundApiKeyCopy); + } } diff --git a/backend/src/entities/api-key/use-cases/get-all-user-api-keys.use.case.ts b/backend/src/entities/api-key/use-cases/get-all-user-api-keys.use.case.ts index 97ec99304..710f07f9c 100644 --- a/backend/src/entities/api-key/use-cases/get-all-user-api-keys.use.case.ts +++ b/backend/src/entities/api-key/use-cases/get-all-user-api-keys.use.case.ts @@ -1,22 +1,22 @@ import { Inject, Injectable } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { FoundApiKeyDS } from '../application/dto/found-api-key.ds.js'; -import { IGetApiKeys } from './api-key-use-cases.interface.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; +import { FoundApiKeyDS } from '../application/dto/found-api-key.ds.js'; import { buildFoundApiKeyDS } from '../utils/build-found-api-key.ds.js'; +import { IGetApiKeys } from './api-key-use-cases.interface.js'; @Injectable() export class GetAllUserApiKeysUseCase extends AbstractUseCase> implements IGetApiKeys { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(userId: string): Promise> { - const foundApiKeys = await this._dbContext.userApiKeysRepository.findApiKeysByUserId(userId); - return foundApiKeys.map((apiKey) => buildFoundApiKeyDS(apiKey)); - } + protected async implementation(userId: string): Promise> { + const foundApiKeys = await this._dbContext.userApiKeysRepository.findApiKeysByUserId(userId); + return foundApiKeys.map((apiKey) => buildFoundApiKeyDS(apiKey)); + } } diff --git a/backend/src/entities/api-key/use-cases/get-user-api-key.use.case.ts b/backend/src/entities/api-key/use-cases/get-user-api-key.use.case.ts index 6547874c4..a90f16a00 100644 --- a/backend/src/entities/api-key/use-cases/get-user-api-key.use.case.ts +++ b/backend/src/entities/api-key/use-cases/get-user-api-key.use.case.ts @@ -1,30 +1,30 @@ import { Inject, Injectable, NotFoundException } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { FindApiKeyDS } from '../application/data-structures/find-api-key.ds.js'; -import { FoundApiKeyDS } from '../application/dto/found-api-key.ds.js'; -import { IGetApiKey } from './api-key-use-cases.interface.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { FindApiKeyDS } from '../application/data-structures/find-api-key.ds.js'; +import { FoundApiKeyDS } from '../application/dto/found-api-key.ds.js'; import { buildFoundApiKeyDS } from '../utils/build-found-api-key.ds.js'; +import { IGetApiKey } from './api-key-use-cases.interface.js'; @Injectable() export class GetUserApiKeyUseCase extends AbstractUseCase implements IGetApiKey { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(apiKeyData: FindApiKeyDS): Promise { - const foundApiKey = await this._dbContext.userApiKeysRepository.findApiKeyByIdAndUserId( - apiKeyData.apiKeyId, - apiKeyData.userId, - ); - if (!foundApiKey) { - throw new NotFoundException(Messages.API_KEY_NOT_FOUND); - } - return buildFoundApiKeyDS(foundApiKey); - } + protected async implementation(apiKeyData: FindApiKeyDS): Promise { + const foundApiKey = await this._dbContext.userApiKeysRepository.findApiKeyByIdAndUserId( + apiKeyData.apiKeyId, + apiKeyData.userId, + ); + if (!foundApiKey) { + throw new NotFoundException(Messages.API_KEY_NOT_FOUND); + } + return buildFoundApiKeyDS(foundApiKey); + } } diff --git a/backend/src/entities/api-key/utils/build-created-api-key-ds.ts b/backend/src/entities/api-key/utils/build-created-api-key-ds.ts index 67bd22378..b5ec58bb4 100644 --- a/backend/src/entities/api-key/utils/build-created-api-key-ds.ts +++ b/backend/src/entities/api-key/utils/build-created-api-key-ds.ts @@ -2,10 +2,10 @@ import { UserApiKeyEntity } from '../api-key.entity.js'; import { CreatedApiKeyDS } from '../application/data-structures/created-api-key.ds.js'; export function buildCreatedApiKeyDS(apiKey: UserApiKeyEntity): CreatedApiKeyDS { - return { - id: apiKey.id, - title: apiKey.title, - hash: apiKey.hash, - created_at: apiKey.created_at, - }; + return { + id: apiKey.id, + title: apiKey.title, + hash: apiKey.hash, + created_at: apiKey.created_at, + }; } diff --git a/backend/src/entities/api-key/utils/build-created-api-key.dto.ts b/backend/src/entities/api-key/utils/build-created-api-key.dto.ts index 97146f5b2..ecc6d6316 100644 --- a/backend/src/entities/api-key/utils/build-created-api-key.dto.ts +++ b/backend/src/entities/api-key/utils/build-created-api-key.dto.ts @@ -3,10 +3,10 @@ import { CreatedApiKeyDS } from '../application/data-structures/created-api-key. import { CreatedApiKeyDto } from '../application/dto/created-api-key.dto.js'; export function buildCreatedApiKeyDto(apiKey: UserApiKeyEntity | CreatedApiKeyDS): CreatedApiKeyDto { - return { - id: apiKey.id, - title: apiKey.title, - hash: apiKey.hash, - created_at: apiKey.created_at, - }; + return { + id: apiKey.id, + title: apiKey.title, + hash: apiKey.hash, + created_at: apiKey.created_at, + }; } diff --git a/backend/src/entities/api-key/utils/build-found-api-key.ds.ts b/backend/src/entities/api-key/utils/build-found-api-key.ds.ts index 820ace73e..e05d8d88b 100644 --- a/backend/src/entities/api-key/utils/build-found-api-key.ds.ts +++ b/backend/src/entities/api-key/utils/build-found-api-key.ds.ts @@ -2,9 +2,9 @@ import { UserApiKeyEntity } from '../api-key.entity.js'; import { FoundApiKeyDS } from '../application/dto/found-api-key.ds.js'; export function buildFoundApiKeyDS(apiKey: UserApiKeyEntity): FoundApiKeyDS { - return { - id: apiKey.id, - title: apiKey.title, - created_at: apiKey.created_at, - }; + return { + id: apiKey.id, + title: apiKey.title, + created_at: apiKey.created_at, + }; } diff --git a/backend/src/entities/api-key/utils/build-found-api-key.dto.ts b/backend/src/entities/api-key/utils/build-found-api-key.dto.ts index 312d01b6b..4ac191b50 100644 --- a/backend/src/entities/api-key/utils/build-found-api-key.dto.ts +++ b/backend/src/entities/api-key/utils/build-found-api-key.dto.ts @@ -3,8 +3,8 @@ import { FoundApiKeyDS } from '../application/dto/found-api-key.ds.js'; import { FoundApiKeyDto } from '../application/dto/found-api-key.dto.js'; export function buildFoundApiKeyDto(apiKey: UserApiKeyEntity | FoundApiKeyDS): FoundApiKeyDto { - return { - id: apiKey.id, - title: apiKey.title, - }; + return { + id: apiKey.id, + title: apiKey.title, + }; } diff --git a/backend/src/entities/api-key/utils/build-new-api-key-entity.ts b/backend/src/entities/api-key/utils/build-new-api-key-entity.ts index 180de5a49..f1fe97b76 100644 --- a/backend/src/entities/api-key/utils/build-new-api-key-entity.ts +++ b/backend/src/entities/api-key/utils/build-new-api-key-entity.ts @@ -3,8 +3,8 @@ import { UserApiKeyEntity } from '../api-key.entity.js'; import { CreateApiKeyDS } from '../application/data-structures/create-api-key.ds.js'; export function buildNewApiKeyEntity(keyData: CreateApiKeyDS): UserApiKeyEntity { - const newApiKey = new UserApiKeyEntity(); - newApiKey.title = keyData.title; - newApiKey.hash = Encryptor.generateApiKey(); - return newApiKey; + const newApiKey = new UserApiKeyEntity(); + newApiKey.title = keyData.title; + newApiKey.hash = Encryptor.generateApiKey(); + return newApiKey; } diff --git a/backend/src/entities/company-favicon/company-favicon.entity.ts b/backend/src/entities/company-favicon/company-favicon.entity.ts index 46f47aec2..9aa36de4e 100644 --- a/backend/src/entities/company-favicon/company-favicon.entity.ts +++ b/backend/src/entities/company-favicon/company-favicon.entity.ts @@ -3,21 +3,25 @@ import { CompanyInfoEntity } from '../company-info/company-info.entity.js'; @Entity('company_favicon') export class CompanyFaviconEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ type: 'bytea', nullable: true }) - image: Buffer; + @Column({ type: 'bytea', nullable: true }) + image: Buffer; - @Column({ type: 'varchar', length: 24, nullable: false, default: 'image/png' }) - mimeType: string; + @Column({ type: 'varchar', length: 24, nullable: false, default: 'image/png' }) + mimeType: string; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - createdAt: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + createdAt: Date; - @OneToOne((_) => CompanyInfoEntity, (company) => company.favicon, { - onDelete: 'CASCADE', - }) - @JoinColumn() - company: Relation; -} \ No newline at end of file + @OneToOne( + (_) => CompanyInfoEntity, + (company) => company.favicon, + { + onDelete: 'CASCADE', + }, + ) + @JoinColumn() + company: Relation; +} diff --git a/backend/src/entities/company-favicon/company-favicon.module.ts b/backend/src/entities/company-favicon/company-favicon.module.ts index 9fd45ae31..08cf2e1e1 100644 --- a/backend/src/entities/company-favicon/company-favicon.module.ts +++ b/backend/src/entities/company-favicon/company-favicon.module.ts @@ -4,8 +4,8 @@ import { CompanyInfoEntity } from '../company-info/company-info.entity.js'; import { CompanyFaviconEntity } from './company-favicon.entity.js'; @Module({ - imports: [TypeOrmModule.forFeature([CompanyInfoEntity, CompanyFaviconEntity])], - providers: [], - exports: [], + imports: [TypeOrmModule.forFeature([CompanyInfoEntity, CompanyFaviconEntity])], + providers: [], + exports: [], }) export class CompanyFaviconModule {} diff --git a/backend/src/entities/company-info/application/data-structures/accept-user-invitation-in-company.ds.ts b/backend/src/entities/company-info/application/data-structures/accept-user-invitation-in-company.ds.ts index d63cef6b2..ede91535c 100644 --- a/backend/src/entities/company-info/application/data-structures/accept-user-invitation-in-company.ds.ts +++ b/backend/src/entities/company-info/application/data-structures/accept-user-invitation-in-company.ds.ts @@ -1,5 +1,5 @@ export class AcceptUserValidationInCompany { - userName: string; - verificationString: string; - userPassword: string; + userName: string; + verificationString: string; + userPassword: string; } diff --git a/backend/src/entities/company-info/application/data-structures/add-company-tab-title.ds.ts b/backend/src/entities/company-info/application/data-structures/add-company-tab-title.ds.ts index d644e4d16..4c00ad5e9 100644 --- a/backend/src/entities/company-info/application/data-structures/add-company-tab-title.ds.ts +++ b/backend/src/entities/company-info/application/data-structures/add-company-tab-title.ds.ts @@ -1,4 +1,4 @@ export class AddCompanyTabTitleDs { - companyId: string; - tab_title: string; + companyId: string; + tab_title: string; } diff --git a/backend/src/entities/company-info/application/data-structures/add-company-tab-title.dto.ts b/backend/src/entities/company-info/application/data-structures/add-company-tab-title.dto.ts index b3560bf78..19eb0e6b4 100644 --- a/backend/src/entities/company-info/application/data-structures/add-company-tab-title.dto.ts +++ b/backend/src/entities/company-info/application/data-structures/add-company-tab-title.dto.ts @@ -2,10 +2,10 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty, IsString, MaxLength, MinLength } from 'class-validator'; export class AddCompanyTabTitleDto { - @ApiProperty({ required: true }) - @IsString() - @IsNotEmpty() - @MinLength(1) - @MaxLength(255) - tab_title: string; + @ApiProperty({ required: true }) + @IsString() + @IsNotEmpty() + @MinLength(1) + @MaxLength(255) + tab_title: string; } diff --git a/backend/src/entities/company-info/application/data-structures/found-company-info.ds.ts b/backend/src/entities/company-info/application/data-structures/found-company-info.ds.ts index ed12f61af..be9d1d55b 100644 --- a/backend/src/entities/company-info/application/data-structures/found-company-info.ds.ts +++ b/backend/src/entities/company-info/application/data-structures/found-company-info.ds.ts @@ -4,61 +4,61 @@ import { FoundCompanyImageInfo } from '../dto/found-company-logo.ro.js'; import { FoundInvitationInCompanyDs } from './found-invitation-in-company.ds.js'; export class FoundUserCompanyInfoDs { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty({ required: false }) - additional_info?: string; + @ApiProperty({ required: false }) + additional_info?: string; - @ApiProperty({ required: false }) - name?: string; + @ApiProperty({ required: false }) + name?: string; - @ApiProperty({ required: false }) - createdAt?: Date; + @ApiProperty({ required: false }) + createdAt?: Date; - @ApiProperty({ required: false }) - updatedAt?: Date; + @ApiProperty({ required: false }) + updatedAt?: Date; - @ApiProperty({ required: false }) - portal_link?: string; + @ApiProperty({ required: false }) + portal_link?: string; - @ApiProperty({ required: false }) - subscriptionLevel?: string; + @ApiProperty({ required: false }) + subscriptionLevel?: string; - @ApiProperty({ required: false }) - is_payment_method_added?: boolean; + @ApiProperty({ required: false }) + is_payment_method_added?: boolean; - @ApiProperty({ required: false }) - is2faEnabled: boolean; + @ApiProperty({ required: false }) + is2faEnabled: boolean; - @ApiProperty() - show_test_connections: boolean; + @ApiProperty() + show_test_connections: boolean; - @ApiProperty({ required: false }) - custom_domain: string | null; + @ApiProperty({ required: false }) + custom_domain: string | null; - @ApiProperty({ required: false, type: FoundCompanyImageInfo }) - logo: FoundCompanyImageInfo; + @ApiProperty({ required: false, type: FoundCompanyImageInfo }) + logo: FoundCompanyImageInfo; - @ApiProperty({ required: false, type: FoundCompanyImageInfo }) - favicon: FoundCompanyImageInfo; + @ApiProperty({ required: false, type: FoundCompanyImageInfo }) + favicon: FoundCompanyImageInfo; - @ApiProperty({ required: false }) - tab_title: string; + @ApiProperty({ required: false }) + tab_title: string; } export class FoundUserFullCompanyInfoDs extends FoundUserCompanyInfoDs { - @ApiProperty({ isArray: true }) - connections: Array; + @ApiProperty({ isArray: true }) + connections: Array; - @ApiProperty({ isArray: true, type: FoundInvitationInCompanyDs }) - invitations: Array; + @ApiProperty({ isArray: true, type: FoundInvitationInCompanyDs }) + invitations: Array; } export class FoundUserEmailCompaniesInfoDs { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty({ required: false }) - name?: string; + @ApiProperty({ required: false }) + name?: string; } diff --git a/backend/src/entities/company-info/application/data-structures/found-company-name.ds.ts b/backend/src/entities/company-info/application/data-structures/found-company-name.ds.ts index 8e4686ed5..670f25ec8 100644 --- a/backend/src/entities/company-info/application/data-structures/found-company-name.ds.ts +++ b/backend/src/entities/company-info/application/data-structures/found-company-name.ds.ts @@ -1,9 +1,9 @@ import { ApiProperty } from '@nestjs/swagger'; export class FoundCompanyNameDs { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - name: string; + @ApiProperty() + name: string; } diff --git a/backend/src/entities/company-info/application/data-structures/found-company-tab-title.ro.ts b/backend/src/entities/company-info/application/data-structures/found-company-tab-title.ro.ts index 126f7fca2..1a9b8a613 100644 --- a/backend/src/entities/company-info/application/data-structures/found-company-tab-title.ro.ts +++ b/backend/src/entities/company-info/application/data-structures/found-company-tab-title.ro.ts @@ -1,3 +1,3 @@ export class FoundCompanyTabTitleRO { - tab_title: string; -} \ No newline at end of file + tab_title: string; +} diff --git a/backend/src/entities/company-info/application/data-structures/found-invitation-in-company.ds.ts b/backend/src/entities/company-info/application/data-structures/found-invitation-in-company.ds.ts index e35aa4d42..d366f62eb 100644 --- a/backend/src/entities/company-info/application/data-structures/found-invitation-in-company.ds.ts +++ b/backend/src/entities/company-info/application/data-structures/found-invitation-in-company.ds.ts @@ -2,24 +2,24 @@ import { ApiProperty } from '@nestjs/swagger'; import { UserRoleEnum } from '../../../user/enums/user-role.enum.js'; export class FoundInvitationInCompanyDs { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty({ required: false }) - verification_string: string | null; + @ApiProperty({ required: false }) + verification_string: string | null; - @ApiProperty({ required: false }) - groupId: string | null; + @ApiProperty({ required: false }) + groupId: string | null; - @ApiProperty({ required: false }) - inviterId: string | null; + @ApiProperty({ required: false }) + inviterId: string | null; - @ApiProperty({ required: false }) - invitedUserEmail: string | null; + @ApiProperty({ required: false }) + invitedUserEmail: string | null; - @ApiProperty({ enum: UserRoleEnum }) - role: UserRoleEnum; + @ApiProperty({ enum: UserRoleEnum }) + role: UserRoleEnum; - @ApiProperty() - createdAt: Date; + @ApiProperty() + createdAt: Date; } diff --git a/backend/src/entities/company-info/application/data-structures/invite-user-in-company-and-connection-group.ds.ts b/backend/src/entities/company-info/application/data-structures/invite-user-in-company-and-connection-group.ds.ts index 545876686..28641a84e 100644 --- a/backend/src/entities/company-info/application/data-structures/invite-user-in-company-and-connection-group.ds.ts +++ b/backend/src/entities/company-info/application/data-structures/invite-user-in-company-and-connection-group.ds.ts @@ -1,9 +1,9 @@ import { UserRoleEnum } from '../../../user/enums/user-role.enum.js'; export class InviteUserInCompanyAndConnectionGroupDs { - inviterId: string; - companyId: string; - groupId: string; - invitedUserEmail: string; - invitedUserCompanyRole: UserRoleEnum; + inviterId: string; + companyId: string; + groupId: string; + invitedUserEmail: string; + invitedUserCompanyRole: UserRoleEnum; } diff --git a/backend/src/entities/company-info/application/data-structures/invited-user-in-company-and-connection-group.ds.ts b/backend/src/entities/company-info/application/data-structures/invited-user-in-company-and-connection-group.ds.ts index fc2ad6dcd..f7ec4e775 100644 --- a/backend/src/entities/company-info/application/data-structures/invited-user-in-company-and-connection-group.ds.ts +++ b/backend/src/entities/company-info/application/data-structures/invited-user-in-company-and-connection-group.ds.ts @@ -2,15 +2,15 @@ import { ApiProperty } from '@nestjs/swagger'; import { UserRoleEnum } from '../../../user/enums/user-role.enum.js'; export class InvitedUserInCompanyAndConnectionGroupDs { - @ApiProperty() - companyId: string; + @ApiProperty() + companyId: string; - @ApiProperty() - groupId: string; + @ApiProperty() + groupId: string; - @ApiProperty() - email: string; + @ApiProperty() + email: string; - @ApiProperty({ enum: UserRoleEnum }) - role: UserRoleEnum; + @ApiProperty({ enum: UserRoleEnum }) + role: UserRoleEnum; } diff --git a/backend/src/entities/company-info/application/data-structures/remove-user-from-company.ds.ts b/backend/src/entities/company-info/application/data-structures/remove-user-from-company.ds.ts index 563b09397..da7f527ec 100644 --- a/backend/src/entities/company-info/application/data-structures/remove-user-from-company.ds.ts +++ b/backend/src/entities/company-info/application/data-structures/remove-user-from-company.ds.ts @@ -1,4 +1,4 @@ export class RemoveUserFromCompanyDs { - userId: string; - companyId: string; + userId: string; + companyId: string; } diff --git a/backend/src/entities/company-info/application/data-structures/revoke-user-invitation.dto.ts b/backend/src/entities/company-info/application/data-structures/revoke-user-invitation.dto.ts index cbeb3dd60..f655c3fd3 100644 --- a/backend/src/entities/company-info/application/data-structures/revoke-user-invitation.dto.ts +++ b/backend/src/entities/company-info/application/data-structures/revoke-user-invitation.dto.ts @@ -1,4 +1,4 @@ export class RevokeUserInvitationDs { - email: string; - companyId: string; + email: string; + companyId: string; } diff --git a/backend/src/entities/company-info/application/data-structures/suspend-users-in-company.ds.ts b/backend/src/entities/company-info/application/data-structures/suspend-users-in-company.ds.ts index add9087d8..1c387f3f0 100644 --- a/backend/src/entities/company-info/application/data-structures/suspend-users-in-company.ds.ts +++ b/backend/src/entities/company-info/application/data-structures/suspend-users-in-company.ds.ts @@ -1,4 +1,4 @@ export class SuspendUsersInCompanyDS { - companyInfoId: string; - usersEmails: Array; + companyInfoId: string; + usersEmails: Array; } diff --git a/backend/src/entities/company-info/application/data-structures/toggle-test-connections-display-mode.ds.ts b/backend/src/entities/company-info/application/data-structures/toggle-test-connections-display-mode.ds.ts index 61032bbab..1d3f32898 100644 --- a/backend/src/entities/company-info/application/data-structures/toggle-test-connections-display-mode.ds.ts +++ b/backend/src/entities/company-info/application/data-structures/toggle-test-connections-display-mode.ds.ts @@ -1,4 +1,4 @@ export class ToggleTestConnectionDisplayModeDs { - userId: string; - displayMode: boolean; + userId: string; + displayMode: boolean; } diff --git a/backend/src/entities/company-info/application/data-structures/update-company-name.ds.ts b/backend/src/entities/company-info/application/data-structures/update-company-name.ds.ts index 5c079e10c..3b64438b1 100644 --- a/backend/src/entities/company-info/application/data-structures/update-company-name.ds.ts +++ b/backend/src/entities/company-info/application/data-structures/update-company-name.ds.ts @@ -1,4 +1,4 @@ export class UpdateCompanyNameDS { - companyId: string; - name: string; + companyId: string; + name: string; } diff --git a/backend/src/entities/company-info/application/data-structures/update-users-2fa-status-in-company.ds.ts b/backend/src/entities/company-info/application/data-structures/update-users-2fa-status-in-company.ds.ts index 3a458ad03..4ef6930fc 100644 --- a/backend/src/entities/company-info/application/data-structures/update-users-2fa-status-in-company.ds.ts +++ b/backend/src/entities/company-info/application/data-structures/update-users-2fa-status-in-company.ds.ts @@ -1,4 +1,4 @@ export class UpdateUsers2faStatusInCompanyDs { - is2faEnabled: boolean; - companyId: string; + is2faEnabled: boolean; + companyId: string; } diff --git a/backend/src/entities/company-info/application/data-structures/update-users-company-roles.ds.ts b/backend/src/entities/company-info/application/data-structures/update-users-company-roles.ds.ts index 29fd1e468..e344472ec 100644 --- a/backend/src/entities/company-info/application/data-structures/update-users-company-roles.ds.ts +++ b/backend/src/entities/company-info/application/data-structures/update-users-company-roles.ds.ts @@ -1,9 +1,9 @@ import { UserRoleEnum } from '../../../user/enums/user-role.enum.js'; export class UpdateUsersCompanyRolesDs { - companyId: string; - users: Array<{ - userId: string; - role: UserRoleEnum; - }>; + companyId: string; + users: Array<{ + userId: string; + role: UserRoleEnum; + }>; } diff --git a/backend/src/entities/company-info/application/data-structures/upload-company-white-label-images.ds.ts b/backend/src/entities/company-info/application/data-structures/upload-company-white-label-images.ds.ts index a8dba111f..52fe29688 100644 --- a/backend/src/entities/company-info/application/data-structures/upload-company-white-label-images.ds.ts +++ b/backend/src/entities/company-info/application/data-structures/upload-company-white-label-images.ds.ts @@ -1,4 +1,4 @@ export class UploadCompanyWhiteLabelImages { - companyId: string; - file: Express.Multer.File; + companyId: string; + file: Express.Multer.File; } diff --git a/backend/src/entities/company-info/application/dto/found-company-logo.ro.ts b/backend/src/entities/company-info/application/dto/found-company-logo.ro.ts index ab6870df3..5c71c379a 100644 --- a/backend/src/entities/company-info/application/dto/found-company-logo.ro.ts +++ b/backend/src/entities/company-info/application/dto/found-company-logo.ro.ts @@ -1,18 +1,18 @@ import { ApiProperty } from '@nestjs/swagger'; export class FoundCompanyImageInfo { - @ApiProperty({ type: 'string', format: 'base64' }) - image: string; + @ApiProperty({ type: 'string', format: 'base64' }) + image: string; - @ApiProperty({ type: 'string' }) - mimeType: string; + @ApiProperty({ type: 'string' }) + mimeType: string; } export class FoundCompanyLogoRO { - @ApiProperty({ type: FoundCompanyImageInfo }) - logo: FoundCompanyImageInfo; + @ApiProperty({ type: FoundCompanyImageInfo }) + logo: FoundCompanyImageInfo; } export class FoundCompanyFaviconRO { - @ApiProperty({ type: FoundCompanyImageInfo }) - favicon: FoundCompanyImageInfo; + @ApiProperty({ type: FoundCompanyImageInfo }) + favicon: FoundCompanyImageInfo; } diff --git a/backend/src/entities/company-info/application/dto/found-company-white-label-properties.ro.ts b/backend/src/entities/company-info/application/dto/found-company-white-label-properties.ro.ts index 984c69a70..44805009c 100644 --- a/backend/src/entities/company-info/application/dto/found-company-white-label-properties.ro.ts +++ b/backend/src/entities/company-info/application/dto/found-company-white-label-properties.ro.ts @@ -1,17 +1,17 @@ import { ApiProperty } from '@nestjs/swagger'; -import { FoundCompanyImageInfo } from './found-company-logo.ro.js'; import { SubscriptionLevelEnum } from '../../../../enums/subscription-level.enum.js'; +import { FoundCompanyImageInfo } from './found-company-logo.ro.js'; export class FoundCompanyWhiteLabelPropertiesRO { - @ApiProperty({ type: FoundCompanyImageInfo, required: false }) - logo: FoundCompanyImageInfo; + @ApiProperty({ type: FoundCompanyImageInfo, required: false }) + logo: FoundCompanyImageInfo; - @ApiProperty({ type: FoundCompanyImageInfo, required: false }) - favicon: FoundCompanyImageInfo; + @ApiProperty({ type: FoundCompanyImageInfo, required: false }) + favicon: FoundCompanyImageInfo; - @ApiProperty({ type: String, required: false }) - tab_title: string; + @ApiProperty({ type: String, required: false }) + tab_title: string; - @ApiProperty({ enum: SubscriptionLevelEnum }) - subscriptionLevel: SubscriptionLevelEnum; + @ApiProperty({ enum: SubscriptionLevelEnum }) + subscriptionLevel: SubscriptionLevelEnum; } diff --git a/backend/src/entities/company-info/application/dto/invite-user-in-company-and-connection-group.dto.ts b/backend/src/entities/company-info/application/dto/invite-user-in-company-and-connection-group.dto.ts index 3cf08e099..a94678ab2 100644 --- a/backend/src/entities/company-info/application/dto/invite-user-in-company-and-connection-group.dto.ts +++ b/backend/src/entities/company-info/application/dto/invite-user-in-company-and-connection-group.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; -import { UserRoleEnum } from '../../../user/enums/user-role.enum.js'; import { IsEmail, IsEnum, IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator'; +import { UserRoleEnum } from '../../../user/enums/user-role.enum.js'; export class InviteUserInCompanyAndConnectionGroupDto { @IsOptional() diff --git a/backend/src/entities/company-info/application/dto/revoke-invitation-request.dto.ts b/backend/src/entities/company-info/application/dto/revoke-invitation-request.dto.ts index 5182444f3..fbfc6ed6c 100644 --- a/backend/src/entities/company-info/application/dto/revoke-invitation-request.dto.ts +++ b/backend/src/entities/company-info/application/dto/revoke-invitation-request.dto.ts @@ -1,10 +1,10 @@ import { ApiProperty } from '@nestjs/swagger'; -import { IsString, IsNotEmpty, IsEmail } from 'class-validator'; +import { IsEmail, IsNotEmpty, IsString } from 'class-validator'; export class RevokeInvitationRequestDto { - @IsString() - @IsNotEmpty() - @IsEmail() - @ApiProperty() - email: string; + @IsString() + @IsNotEmpty() + @IsEmail() + @ApiProperty() + email: string; } diff --git a/backend/src/entities/company-info/application/dto/suspend-users-in-company.dto.ts b/backend/src/entities/company-info/application/dto/suspend-users-in-company.dto.ts index dcac6fe0d..9f69edf7c 100644 --- a/backend/src/entities/company-info/application/dto/suspend-users-in-company.dto.ts +++ b/backend/src/entities/company-info/application/dto/suspend-users-in-company.dto.ts @@ -2,10 +2,10 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsArray, IsEmail, IsNotEmpty, IsString } from 'class-validator'; export class SuspendUsersInCompanyDto { - @ApiProperty() - @IsArray() - @IsString({ each: true }) - @IsNotEmpty({ each: true }) - @IsEmail({}, { each: true }) - usersEmails: Array; + @ApiProperty() + @IsArray() + @IsString({ each: true }) + @IsNotEmpty({ each: true }) + @IsEmail({}, { each: true }) + usersEmails: Array; } diff --git a/backend/src/entities/company-info/application/dto/token-expiration-response.dto.ts b/backend/src/entities/company-info/application/dto/token-expiration-response.dto.ts index 1c43a798e..dde9f340b 100644 --- a/backend/src/entities/company-info/application/dto/token-expiration-response.dto.ts +++ b/backend/src/entities/company-info/application/dto/token-expiration-response.dto.ts @@ -1,9 +1,9 @@ import { ApiProperty } from '@nestjs/swagger'; export class TokenExpirationResponseDto { - @ApiProperty() - expires: Date; + @ApiProperty() + expires: Date; - @ApiProperty() - isTemporary: boolean; + @ApiProperty() + isTemporary: boolean; } diff --git a/backend/src/entities/company-info/application/dto/update-company-name.dto.ts b/backend/src/entities/company-info/application/dto/update-company-name.dto.ts index fc15f0eaa..d6511387b 100644 --- a/backend/src/entities/company-info/application/dto/update-company-name.dto.ts +++ b/backend/src/entities/company-info/application/dto/update-company-name.dto.ts @@ -2,9 +2,9 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty, IsString, MaxLength } from 'class-validator'; export class UpdateCompanyNameDto { - @ApiProperty() - @IsString() - @IsNotEmpty() - @MaxLength(255) - name: string; + @ApiProperty() + @IsString() + @IsNotEmpty() + @MaxLength(255) + name: string; } diff --git a/backend/src/entities/company-info/application/dto/update-users-2fa-status-in-company.dto.ts b/backend/src/entities/company-info/application/dto/update-users-2fa-status-in-company.dto.ts index 5bea47bae..73024de05 100644 --- a/backend/src/entities/company-info/application/dto/update-users-2fa-status-in-company.dto.ts +++ b/backend/src/entities/company-info/application/dto/update-users-2fa-status-in-company.dto.ts @@ -2,8 +2,8 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsBoolean, IsNotEmpty } from 'class-validator'; export class UpdateUsers2faStatusInCompanyDto { - @ApiProperty() - @IsNotEmpty() - @IsBoolean() - readonly is2faEnabled: boolean; + @ApiProperty() + @IsNotEmpty() + @IsBoolean() + readonly is2faEnabled: boolean; } diff --git a/backend/src/entities/company-info/application/dto/update-users-roles-resuest.dto.ts b/backend/src/entities/company-info/application/dto/update-users-roles-resuest.dto.ts index 0309e6e61..070a35578 100644 --- a/backend/src/entities/company-info/application/dto/update-users-roles-resuest.dto.ts +++ b/backend/src/entities/company-info/application/dto/update-users-roles-resuest.dto.ts @@ -3,21 +3,21 @@ import { IsArray, IsEnum, IsNotEmpty, IsString, IsUUID, ValidateNested } from 'c import { UserRoleEnum } from '../../../user/enums/user-role.enum.js'; export class UpdateUserRoleRequestDto { - @ApiProperty() - @IsString() - @IsNotEmpty() - @IsUUID() - userId: string; + @ApiProperty() + @IsString() + @IsNotEmpty() + @IsUUID() + userId: string; - @ApiProperty() - @IsNotEmpty() - @IsEnum({ enum: UserRoleEnum }) - role: UserRoleEnum; + @ApiProperty() + @IsNotEmpty() + @IsEnum({ enum: UserRoleEnum }) + role: UserRoleEnum; } export class UpdateUsersRolesRequestDto { - @ApiProperty({ type: UpdateUserRoleRequestDto, isArray: true }) - @IsArray() - @ValidateNested({ each: true }) - users: Array; + @ApiProperty({ type: UpdateUserRoleRequestDto, isArray: true }) + @IsArray() + @ValidateNested({ each: true }) + users: Array; } diff --git a/backend/src/entities/company-info/application/dto/verify-company-invitation-request-dto.ts b/backend/src/entities/company-info/application/dto/verify-company-invitation-request-dto.ts index 3af437f1f..ccdf6cab7 100644 --- a/backend/src/entities/company-info/application/dto/verify-company-invitation-request-dto.ts +++ b/backend/src/entities/company-info/application/dto/verify-company-invitation-request-dto.ts @@ -2,14 +2,14 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty, IsString, MaxLength } from 'class-validator'; export class VerifyCompanyInvitationRequestDto { - @IsString() - @IsNotEmpty() - @MaxLength(255) - @ApiProperty() - password: string; + @IsString() + @IsNotEmpty() + @MaxLength(255) + @ApiProperty() + password: string; - @IsString() - @IsNotEmpty() - @ApiProperty() - userName: string; + @IsString() + @IsNotEmpty() + @ApiProperty() + userName: string; } diff --git a/backend/src/entities/company-info/company-info-helper.service.ts b/backend/src/entities/company-info/company-info-helper.service.ts index b280bc471..e0d74d112 100644 --- a/backend/src/entities/company-info/company-info-helper.service.ts +++ b/backend/src/entities/company-info/company-info-helper.service.ts @@ -1,33 +1,33 @@ import { Inject, Injectable } from '@nestjs/common'; -import { BaseType } from '../../common/data-injection.tokens.js'; -import { SaasCompanyGatewayService } from '../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; import { IGlobalDatabaseContext } from '../../common/application/global-database-context.interface.js'; -import { isSaaS } from '../../helpers/app/is-saas.js'; +import { BaseType } from '../../common/data-injection.tokens.js'; import { SubscriptionLevelEnum } from '../../enums/subscription-level.enum.js'; +import { isSaaS } from '../../helpers/app/is-saas.js'; import { Constants } from '../../helpers/constants/constants.js'; +import { SaasCompanyGatewayService } from '../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; @Injectable() export class CompanyInfoHelperService { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private readonly saasCompanyGatewayService: SaasCompanyGatewayService, - ) {} + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly saasCompanyGatewayService: SaasCompanyGatewayService, + ) {} - public async canInviteMoreUsers(companyId: string): Promise { - if (!isSaaS() || process.env.NODE_ENV === 'test') { - return true; - } + public async canInviteMoreUsers(companyId: string): Promise { + if (!isSaaS() || process.env.NODE_ENV === 'test') { + return true; + } - const companyInformationFromSaaS = await this.saasCompanyGatewayService.getCompanyInfo(companyId); + const companyInformationFromSaaS = await this.saasCompanyGatewayService.getCompanyInfo(companyId); - const countUsersInCompany = await this._dbContext.userRepository.countUsersInCompany(companyId); - const countInvitationsInCompany = - await this._dbContext.invitationInCompanyRepository.countNonExpiredInvitationsInCompany(companyId); + const countUsersInCompany = await this._dbContext.userRepository.countUsersInCompany(companyId); + const countInvitationsInCompany = + await this._dbContext.invitationInCompanyRepository.countNonExpiredInvitationsInCompany(companyId); - if (companyInformationFromSaaS.subscriptionLevel === SubscriptionLevelEnum.FREE_PLAN) { - return countUsersInCompany + countInvitationsInCompany < Constants.FREE_PLAN_USERS_COUNT; - } - return true; - } + if (companyInformationFromSaaS.subscriptionLevel === SubscriptionLevelEnum.FREE_PLAN) { + return countUsersInCompany + countInvitationsInCompany < Constants.FREE_PLAN_USERS_COUNT; + } + return true; + } } diff --git a/backend/src/entities/company-info/company-info.controller.ts b/backend/src/entities/company-info/company-info.controller.ts index fe7007a0e..83b888128 100644 --- a/backend/src/entities/company-info/company-info.controller.ts +++ b/backend/src/entities/company-info/company-info.controller.ts @@ -25,28 +25,35 @@ import { Throttle } from '@nestjs/throttler'; import { Request, Response } from 'express'; import { UseCaseType } from '../../common/data-injection.tokens.js'; import { SlugUuid } from '../../decorators/slug-uuid.decorator.js'; +import { Timeout } from '../../decorators/timeout.decorator.js'; import { UserId } from '../../decorators/user-id.decorator.js'; import { InTransactionEnum } from '../../enums/in-transaction.enum.js'; import { Messages } from '../../exceptions/text/messages.js'; import { CompanyAdminGuard } from '../../guards/company-admin.guard.js'; import { CompanyUserGuard } from '../../guards/company-user.guard.js'; +import { PaidFeatureGuard } from '../../guards/paid-feature.guard.js'; +import { isTest } from '../../helpers/app/is-test.js'; import { Constants } from '../../helpers/constants/constants.js'; import { ValidationHelper } from '../../helpers/validators/validation-helper.js'; import { SentryInterceptor } from '../../interceptors/sentry.interceptor.js'; import { SuccessResponse } from '../../microservices/saas-microservice/data-structures/common-responce.ds.js'; +import { TurnstileService } from '../../shared/services/turnstile.service.js'; import { SimpleFoundUserInCompanyInfoDs } from '../user/dto/found-user.dto.js'; import { ITokenExp } from '../user/utils/generate-gwt-token.js'; import { getCookieDomainOptions } from '../user/utils/get-cookie-domain-options.js'; +import { AddCompanyTabTitleDto } from './application/data-structures/add-company-tab-title.dto.js'; import { FoundUserCompanyInfoDs, FoundUserEmailCompaniesInfoDs, FoundUserFullCompanyInfoDs, } from './application/data-structures/found-company-info.ds.js'; import { FoundCompanyNameDs } from './application/data-structures/found-company-name.ds.js'; +import { FoundCompanyTabTitleRO } from './application/data-structures/found-company-tab-title.ro.js'; import { InvitedUserInCompanyAndConnectionGroupDs } from './application/data-structures/invited-user-in-company-and-connection-group.ds.js'; import { ToggleTestConnectionDisplayModeDs } from './application/data-structures/toggle-test-connections-display-mode.ds.js'; import { UpdateUsers2faStatusInCompanyDs } from './application/data-structures/update-users-2fa-status-in-company.ds.js'; import { FoundCompanyFaviconRO, FoundCompanyLogoRO } from './application/dto/found-company-logo.ro.js'; +import { FoundCompanyWhiteLabelPropertiesRO } from './application/dto/found-company-white-label-properties.ro.js'; import { InviteUserInCompanyAndConnectionGroupDto } from './application/dto/invite-user-in-company-and-connection-group.dto.js'; import { RevokeInvitationRequestDto } from './application/dto/revoke-invitation-request.dto.js'; import { SuspendUsersInCompanyDto } from './application/dto/suspend-users-in-company.dto.js'; @@ -81,13 +88,6 @@ import { IUploadCompanyWhiteLabelImages, IVerifyInviteUserInCompanyAndConnectionGroup, } from './use-cases/company-info-use-cases.interface.js'; -import { AddCompanyTabTitleDto } from './application/data-structures/add-company-tab-title.dto.js'; -import { FoundCompanyTabTitleRO } from './application/data-structures/found-company-tab-title.ro.js'; -import { FoundCompanyWhiteLabelPropertiesRO } from './application/dto/found-company-white-label-properties.ro.js'; -import { PaidFeatureGuard } from '../../guards/paid-feature.guard.js'; -import { isTest } from '../../helpers/app/is-test.js'; -import { TurnstileService } from '../../shared/services/turnstile.service.js'; -import { Timeout } from '../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/company-info/company-info.entity.ts b/backend/src/entities/company-info/company-info.entity.ts index 44516b69c..725c97cc4 100644 --- a/backend/src/entities/company-info/company-info.entity.ts +++ b/backend/src/entities/company-info/company-info.entity.ts @@ -1,69 +1,97 @@ import { BeforeInsert, Column, Entity, OneToMany, OneToOne, PrimaryColumn, Relation } from 'typeorm'; -import { UserEntity } from '../user/user.entity.js'; -import { ConnectionEntity } from '../connection/connection.entity.js'; -import { InvitationInCompanyEntity } from './invitation-in-company/invitation-in-company.entity.js'; -import { generateCompanyName } from './utils/get-company-name.js'; -import { CompanyLogoEntity } from '../company-logo/company-logo.entity.js'; import { CompanyFaviconEntity } from '../company-favicon/company-favicon.entity.js'; +import { CompanyLogoEntity } from '../company-logo/company-logo.entity.js'; import { CompanyTabTitleEntity } from '../company-tab-title/company-tab-title.entity.js'; +import { ConnectionEntity } from '../connection/connection.entity.js'; +import { UserEntity } from '../user/user.entity.js'; import { UserSecretEntity } from '../user-secret/user-secret.entity.js'; +import { InvitationInCompanyEntity } from './invitation-in-company/invitation-in-company.entity.js'; +import { generateCompanyName } from './utils/get-company-name.js'; @Entity('company_info') export class CompanyInfoEntity { - @PrimaryColumn('uuid') - id: string; + @PrimaryColumn('uuid') + id: string; - @OneToMany((_) => UserEntity, (user) => user.company, { - onDelete: 'NO ACTION', - }) - users: Relation[]; + @OneToMany( + (_) => UserEntity, + (user) => user.company, + { + onDelete: 'NO ACTION', + }, + ) + users: Relation[]; - @Column({ type: 'varchar', length: 255, unique: false, nullable: true }) - name: string; + @Column({ type: 'varchar', length: 255, unique: false, nullable: true }) + name: string; - @Column({ type: 'boolean', default: false }) - is2faEnabled: boolean; + @Column({ type: 'boolean', default: false }) + is2faEnabled: boolean; - @Column({ type: 'boolean', default: true }) - show_test_connections: boolean; + @Column({ type: 'boolean', default: true }) + show_test_connections: boolean; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - createdAt: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + createdAt: Date; - @BeforeInsert() - getRandomName(): void { - if (!this.name) { - this.name = generateCompanyName(); - } - } + @BeforeInsert() + getRandomName(): void { + if (!this.name) { + this.name = generateCompanyName(); + } + } - @OneToMany((_) => ConnectionEntity, (connection) => connection.company, { - onDelete: 'NO ACTION', - }) - connections: Relation[]; + @OneToMany( + (_) => ConnectionEntity, + (connection) => connection.company, + { + onDelete: 'NO ACTION', + }, + ) + connections: Relation[]; - @OneToMany((_) => InvitationInCompanyEntity, (invitation) => invitation.company, { - onDelete: 'NO ACTION', - }) - invitations: Relation[]; + @OneToMany( + (_) => InvitationInCompanyEntity, + (invitation) => invitation.company, + { + onDelete: 'NO ACTION', + }, + ) + invitations: Relation[]; - @OneToOne((_) => CompanyLogoEntity, (logo) => logo.company, { - onDelete: 'NO ACTION', - }) - logo: Relation; + @OneToOne( + (_) => CompanyLogoEntity, + (logo) => logo.company, + { + onDelete: 'NO ACTION', + }, + ) + logo: Relation; - @OneToOne((_) => CompanyFaviconEntity, (favicon) => favicon.company, { - onDelete: 'NO ACTION', - }) - favicon: Relation; + @OneToOne( + (_) => CompanyFaviconEntity, + (favicon) => favicon.company, + { + onDelete: 'NO ACTION', + }, + ) + favicon: Relation; - @OneToOne((_) => CompanyTabTitleEntity, (tab_title) => tab_title.company, { - onDelete: 'NO ACTION', - }) - tab_title: Relation; + @OneToOne( + (_) => CompanyTabTitleEntity, + (tab_title) => tab_title.company, + { + onDelete: 'NO ACTION', + }, + ) + tab_title: Relation; - @OneToMany((_) => UserSecretEntity, (secret) => secret.company, { - onDelete: 'NO ACTION', - }) - secrets: Relation[]; + @OneToMany( + (_) => UserSecretEntity, + (secret) => secret.company, + { + onDelete: 'NO ACTION', + }, + ) + secrets: Relation[]; } diff --git a/backend/src/entities/company-info/company-info.module.ts b/backend/src/entities/company-info/company-info.module.ts index 1d32327b2..1c4348344 100644 --- a/backend/src/entities/company-info/company-info.module.ts +++ b/backend/src/entities/company-info/company-info.module.ts @@ -1,10 +1,11 @@ import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthMiddleware } from '../../authorization/auth.middleware.js'; import { GlobalDatabaseContext } from '../../common/application/global-database-context.js'; import { BaseType, UseCaseType } from '../../common/data-injection.tokens.js'; import { CompanyLogoEntity } from '../company-logo/company-logo.entity.js'; -import { ConnectionPropertiesEntity } from '../connection-properties/connection-properties.entity.js'; import { ConnectionEntity } from '../connection/connection.entity.js'; +import { ConnectionPropertiesEntity } from '../connection-properties/connection-properties.entity.js'; import { CustomFieldsEntity } from '../custom-field/custom-fields.entity.js'; import { GroupEntity } from '../group/group.entity.js'; import { LogOutEntity } from '../log-out/log-out.entity.js'; @@ -14,12 +15,17 @@ import { TableSettingsEntity } from '../table-settings/common-table-settings/tab import { UserEntity } from '../user/user.entity.js'; import { TableWidgetEntity } from '../widget/table-widget.entity.js'; import { CompanyInfoController } from './company-info.controller.js'; +import { CompanyInfoHelperService } from './company-info-helper.service.js'; +import { AddCompanyTabTitleUseCase } from './use-cases/add-company-tab-title.use.case.js'; import { CheckIsVerificationLinkAvailable } from './use-cases/check-verification-link.available.use.case.js'; import { DeleteCompanyFaviconUseCase } from './use-cases/delete-company-favicon.use.case.js'; import { DeleteCompanyLogoUseCase } from './use-cases/delete-company-logo.use.case.js'; +import { DeleteCompanyTabTitleUseCase } from './use-cases/delete-company-tab-title.use.case.js'; import { DeleteCompanyUseCase } from './use-cases/delete-company-use-case.js'; import { FindCompanyFaviconUseCase } from './use-cases/find-company-favicon.use.case.js'; import { FindCompanyLogoUseCase } from './use-cases/find-company-logo.use.case.js'; +import { FindCompanyTabTitleUseCase } from './use-cases/find-company-tab-title.use.case.js'; +import { FindCompanyWhiteLabelPropertiesUseCase } from './use-cases/find-company-white-label-properties.use.case.js'; import { GetAllUsersInCompanyUseCase } from './use-cases/get-all-users-in-company.use.case.js'; import { GetCompanyNameUseCase } from './use-cases/get-company-name.use.case.js'; import { GetUserCompanyFullInfoUseCase } from './use-cases/get-full-user-company-info.use.case.js'; @@ -37,174 +43,168 @@ import { UpdateUses2faStatusInCompanyUseCase } from './use-cases/update-uses-2fa import { UploadCompanyFaviconUseCase } from './use-cases/upload-company-favicon.use.case.js'; import { UploadCompanyLogoUseCase } from './use-cases/upload-company-logo-use-case.js'; import { VerifyInviteUserInCompanyAndConnectionGroupUseCase } from './use-cases/verify-invite-user-in-company.use.case.js'; -import { AuthMiddleware } from '../../authorization/auth.middleware.js'; -import { AddCompanyTabTitleUseCase } from './use-cases/add-company-tab-title.use.case.js'; -import { FindCompanyTabTitleUseCase } from './use-cases/find-company-tab-title.use.case.js'; -import { DeleteCompanyTabTitleUseCase } from './use-cases/delete-company-tab-title.use.case.js'; -import { FindCompanyWhiteLabelPropertiesUseCase } from './use-cases/find-company-white-label-properties.use.case.js'; -import { CompanyInfoHelperService } from './company-info-helper.service.js'; @Module({ - imports: [ - TypeOrmModule.forFeature([ - ConnectionEntity, - UserEntity, - GroupEntity, - PermissionEntity, - TableSettingsEntity, - TableLogsEntity, - CustomFieldsEntity, - TableWidgetEntity, - ConnectionPropertiesEntity, - CompanyLogoEntity, - LogOutEntity, - ]), - ], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.INVITE_USER_IN_COMPANY_AND_CONNECTION_GROUP, - useClass: InviteUserInCompanyAndConnectionGroupUseCase, - }, - { - provide: UseCaseType.VERIFY_INVITE_USER_IN_COMPANY_AND_CONNECTION_GROUP, - useClass: VerifyInviteUserInCompanyAndConnectionGroupUseCase, - }, - { - provide: UseCaseType.GET_USER_COMPANY, - useClass: GetUserCompanyUseCase, - }, - { - provide: UseCaseType.GET_FULL_USER_COMPANIES_INFO, - useClass: GetUserCompanyFullInfoUseCase, - }, - { - provide: UseCaseType.GET_USER_EMAIL_COMPANIES, - useClass: GetUserEmailCompaniesUseCase, - }, - { - provide: UseCaseType.GET_USERS_IN_COMPANY, - useClass: GetAllUsersInCompanyUseCase, - }, - { - provide: UseCaseType.REMOVE_USER_FROM_COMPANY, - useClass: RemoveUserFromCompanyUseCase, - }, - { - provide: UseCaseType.REVOKE_INVITATION_IN_COMPANY, - useClass: RevokeUserInvitationInCompanyUseCase, - }, - { - provide: UseCaseType.UPDATE_COMPANY_NAME, - useClass: UpdateCompanyNameUseCase, - }, - { - provide: UseCaseType.GET_COMPANY_NAME, - useClass: GetCompanyNameUseCase, - }, - { - provide: UseCaseType.UPDATE_USERS_COMPANY_ROLES, - useClass: UpdateUsersCompanyRolesUseCase, - }, - { - provide: UseCaseType.DELETE_COMPANY, - useClass: DeleteCompanyUseCase, - }, - { - provide: UseCaseType.CHECK_IS_VERIFICATION_LINK_AVAILABLE, - useClass: CheckIsVerificationLinkAvailable, - }, - { - provide: UseCaseType.UPDATE_USERS_2FA_STATUS_IN_COMPANY, - useClass: UpdateUses2faStatusInCompanyUseCase, - }, - { - provide: UseCaseType.SUSPEND_USERS_IN_COMPANY, - useClass: SuspendUsersInCompanyUseCase, - }, - { - provide: UseCaseType.UNSUSPEND_USERS_IN_COMPANY, - useClass: UnsuspendUsersInCompanyUseCase, - }, - { - provide: UseCaseType.TOGGLE_TEST_CONNECTIONS_DISPLAY_MODE_IN_COMPANY, - useClass: ToggleCompanyTestConnectionsDisplayModeUseCase, - }, - { - provide: UseCaseType.UPLOAD_COMPANY_LOGO, - useClass: UploadCompanyLogoUseCase, - }, - { - provide: UseCaseType.FIND_COMPANY_LOGO, - useClass: FindCompanyLogoUseCase, - }, - { - provide: UseCaseType.DELETE_COMPANY_LOGO, - useClass: DeleteCompanyLogoUseCase, - }, - { - provide: UseCaseType.DELETE_COMPANY_FAVICON, - useClass: DeleteCompanyFaviconUseCase, - }, - { - provide: UseCaseType.FIND_COMPANY_FAVICON, - useClass: FindCompanyFaviconUseCase, - }, - { - provide: UseCaseType.UPLOAD_COMPANY_FAVICON, - useClass: UploadCompanyFaviconUseCase, - }, - { - provide: UseCaseType.ADD_COMPANY_TAB_TITLE, - useClass: AddCompanyTabTitleUseCase, - }, - { - provide: UseCaseType.FIND_COMPANY_TAB_TITLE, - useClass: FindCompanyTabTitleUseCase, - }, - { - provide: UseCaseType.DELETE_COMPANY_TAB_TITLE, - useClass: DeleteCompanyTabTitleUseCase, - }, - { - provide: UseCaseType.GET_COMPANY_WHITE_LABEL_PROPERTIES, - useClass: FindCompanyWhiteLabelPropertiesUseCase, - }, - CompanyInfoHelperService, - ], - controllers: [CompanyInfoController], + imports: [ + TypeOrmModule.forFeature([ + ConnectionEntity, + UserEntity, + GroupEntity, + PermissionEntity, + TableSettingsEntity, + TableLogsEntity, + CustomFieldsEntity, + TableWidgetEntity, + ConnectionPropertiesEntity, + CompanyLogoEntity, + LogOutEntity, + ]), + ], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.INVITE_USER_IN_COMPANY_AND_CONNECTION_GROUP, + useClass: InviteUserInCompanyAndConnectionGroupUseCase, + }, + { + provide: UseCaseType.VERIFY_INVITE_USER_IN_COMPANY_AND_CONNECTION_GROUP, + useClass: VerifyInviteUserInCompanyAndConnectionGroupUseCase, + }, + { + provide: UseCaseType.GET_USER_COMPANY, + useClass: GetUserCompanyUseCase, + }, + { + provide: UseCaseType.GET_FULL_USER_COMPANIES_INFO, + useClass: GetUserCompanyFullInfoUseCase, + }, + { + provide: UseCaseType.GET_USER_EMAIL_COMPANIES, + useClass: GetUserEmailCompaniesUseCase, + }, + { + provide: UseCaseType.GET_USERS_IN_COMPANY, + useClass: GetAllUsersInCompanyUseCase, + }, + { + provide: UseCaseType.REMOVE_USER_FROM_COMPANY, + useClass: RemoveUserFromCompanyUseCase, + }, + { + provide: UseCaseType.REVOKE_INVITATION_IN_COMPANY, + useClass: RevokeUserInvitationInCompanyUseCase, + }, + { + provide: UseCaseType.UPDATE_COMPANY_NAME, + useClass: UpdateCompanyNameUseCase, + }, + { + provide: UseCaseType.GET_COMPANY_NAME, + useClass: GetCompanyNameUseCase, + }, + { + provide: UseCaseType.UPDATE_USERS_COMPANY_ROLES, + useClass: UpdateUsersCompanyRolesUseCase, + }, + { + provide: UseCaseType.DELETE_COMPANY, + useClass: DeleteCompanyUseCase, + }, + { + provide: UseCaseType.CHECK_IS_VERIFICATION_LINK_AVAILABLE, + useClass: CheckIsVerificationLinkAvailable, + }, + { + provide: UseCaseType.UPDATE_USERS_2FA_STATUS_IN_COMPANY, + useClass: UpdateUses2faStatusInCompanyUseCase, + }, + { + provide: UseCaseType.SUSPEND_USERS_IN_COMPANY, + useClass: SuspendUsersInCompanyUseCase, + }, + { + provide: UseCaseType.UNSUSPEND_USERS_IN_COMPANY, + useClass: UnsuspendUsersInCompanyUseCase, + }, + { + provide: UseCaseType.TOGGLE_TEST_CONNECTIONS_DISPLAY_MODE_IN_COMPANY, + useClass: ToggleCompanyTestConnectionsDisplayModeUseCase, + }, + { + provide: UseCaseType.UPLOAD_COMPANY_LOGO, + useClass: UploadCompanyLogoUseCase, + }, + { + provide: UseCaseType.FIND_COMPANY_LOGO, + useClass: FindCompanyLogoUseCase, + }, + { + provide: UseCaseType.DELETE_COMPANY_LOGO, + useClass: DeleteCompanyLogoUseCase, + }, + { + provide: UseCaseType.DELETE_COMPANY_FAVICON, + useClass: DeleteCompanyFaviconUseCase, + }, + { + provide: UseCaseType.FIND_COMPANY_FAVICON, + useClass: FindCompanyFaviconUseCase, + }, + { + provide: UseCaseType.UPLOAD_COMPANY_FAVICON, + useClass: UploadCompanyFaviconUseCase, + }, + { + provide: UseCaseType.ADD_COMPANY_TAB_TITLE, + useClass: AddCompanyTabTitleUseCase, + }, + { + provide: UseCaseType.FIND_COMPANY_TAB_TITLE, + useClass: FindCompanyTabTitleUseCase, + }, + { + provide: UseCaseType.DELETE_COMPANY_TAB_TITLE, + useClass: DeleteCompanyTabTitleUseCase, + }, + { + provide: UseCaseType.GET_COMPANY_WHITE_LABEL_PROPERTIES, + useClass: FindCompanyWhiteLabelPropertiesUseCase, + }, + CompanyInfoHelperService, + ], + controllers: [CompanyInfoController], }) export class CompanyInfoModule implements NestModule { - public configure(consumer: MiddlewareConsumer): any { - consumer - .apply(AuthMiddleware) - .forRoutes( - { path: '/company/user/:companyId', method: RequestMethod.PUT }, - { path: '/company/my', method: RequestMethod.GET }, - { path: '/company/my', method: RequestMethod.DELETE }, - { path: '/company/my/full', method: RequestMethod.GET }, - { path: '/company/users/:companyId', method: RequestMethod.GET }, - { path: '/company/:companyId/user/:userId', method: RequestMethod.DELETE }, - { path: '/company/invitation/revoke/:companyId', method: RequestMethod.PUT }, - { path: '/company/name/:companyId', method: RequestMethod.PUT }, - { path: '/company/users/roles/:companyId', method: RequestMethod.PUT }, - { path: '/company/2fa/:companyId', method: RequestMethod.PUT }, - { path: '/company/users/suspend/:companyId', method: RequestMethod.PUT }, - { path: '/company/users/unsuspend/:companyId', method: RequestMethod.PUT }, - { path: '/company/connections/display/', method: RequestMethod.PUT }, - { path: '/company/logo/:companyId', method: RequestMethod.POST }, - { path: '/company/logo/:companyId', method: RequestMethod.GET }, - { path: '/company/logo/:companyId', method: RequestMethod.DELETE }, - { path: '/company/favicon/:companyId', method: RequestMethod.POST }, - { path: '/company/favicon/:companyId', method: RequestMethod.GET }, - { path: '/company/favicon/:companyId', method: RequestMethod.DELETE }, - { path: '/company/tab-title/:companyId', method: RequestMethod.POST }, - { path: '/company/tab-title/:companyId', method: RequestMethod.GET }, - { path: '/company/tab-title/:companyId', method: RequestMethod.DELETE }, - { path: '/company/white-label-properties/:companyId', method: RequestMethod.GET }, - ); - } + public configure(consumer: MiddlewareConsumer): any { + consumer + .apply(AuthMiddleware) + .forRoutes( + { path: '/company/user/:companyId', method: RequestMethod.PUT }, + { path: '/company/my', method: RequestMethod.GET }, + { path: '/company/my', method: RequestMethod.DELETE }, + { path: '/company/my/full', method: RequestMethod.GET }, + { path: '/company/users/:companyId', method: RequestMethod.GET }, + { path: '/company/:companyId/user/:userId', method: RequestMethod.DELETE }, + { path: '/company/invitation/revoke/:companyId', method: RequestMethod.PUT }, + { path: '/company/name/:companyId', method: RequestMethod.PUT }, + { path: '/company/users/roles/:companyId', method: RequestMethod.PUT }, + { path: '/company/2fa/:companyId', method: RequestMethod.PUT }, + { path: '/company/users/suspend/:companyId', method: RequestMethod.PUT }, + { path: '/company/users/unsuspend/:companyId', method: RequestMethod.PUT }, + { path: '/company/connections/display/', method: RequestMethod.PUT }, + { path: '/company/logo/:companyId', method: RequestMethod.POST }, + { path: '/company/logo/:companyId', method: RequestMethod.GET }, + { path: '/company/logo/:companyId', method: RequestMethod.DELETE }, + { path: '/company/favicon/:companyId', method: RequestMethod.POST }, + { path: '/company/favicon/:companyId', method: RequestMethod.GET }, + { path: '/company/favicon/:companyId', method: RequestMethod.DELETE }, + { path: '/company/tab-title/:companyId', method: RequestMethod.POST }, + { path: '/company/tab-title/:companyId', method: RequestMethod.GET }, + { path: '/company/tab-title/:companyId', method: RequestMethod.DELETE }, + { path: '/company/white-label-properties/:companyId', method: RequestMethod.GET }, + ); + } } diff --git a/backend/src/entities/company-info/invitation-in-company/invitation-in-company.entity.ts b/backend/src/entities/company-info/invitation-in-company/invitation-in-company.entity.ts index cd0cb5c5c..5fa0333e5 100644 --- a/backend/src/entities/company-info/invitation-in-company/invitation-in-company.entity.ts +++ b/backend/src/entities/company-info/invitation-in-company/invitation-in-company.entity.ts @@ -1,66 +1,70 @@ import { - AfterLoad, - BeforeInsert, - BeforeUpdate, - Column, - Entity, - JoinColumn, - ManyToOne, - PrimaryGeneratedColumn, - Relation, + AfterLoad, + BeforeInsert, + BeforeUpdate, + Column, + Entity, + JoinColumn, + ManyToOne, + PrimaryGeneratedColumn, + Relation, } from 'typeorm'; -import { CompanyInfoEntity } from '../company-info.entity.js'; import { UserRoleEnum } from '../../user/enums/user-role.enum.js'; +import { CompanyInfoEntity } from '../company-info.entity.js'; @Entity('invitation_in_company') export class InvitationInCompanyEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ default: null }) - verification_string: string | null; + @Column({ default: null }) + verification_string: string | null; - @Column({ default: null }) - groupId: string | null; + @Column({ default: null }) + groupId: string | null; - @Column({ default: null }) - inviterId: string | null; + @Column({ default: null }) + inviterId: string | null; - @Column({ default: null }) - invitedUserEmail: string | null; + @Column({ default: null }) + invitedUserEmail: string | null; - @Column('enum', { - nullable: false, - enum: UserRoleEnum, - default: UserRoleEnum.USER, - }) - role: UserRoleEnum; + @Column('enum', { + nullable: false, + enum: UserRoleEnum, + default: UserRoleEnum.USER, + }) + role: UserRoleEnum; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - createdAt: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + createdAt: Date; - @ManyToOne((_) => CompanyInfoEntity, (companyInfo) => companyInfo.invitations, { onDelete: 'CASCADE' }) - @JoinColumn() - company: Relation; + @ManyToOne( + (_) => CompanyInfoEntity, + (companyInfo) => companyInfo.invitations, + { onDelete: 'CASCADE' }, + ) + @JoinColumn() + company: Relation; - @BeforeInsert() - beforeInsertActions() { - this.emailToLowerCase(); - } + @BeforeInsert() + beforeInsertActions() { + this.emailToLowerCase(); + } - @BeforeUpdate() - beforeUpdateActions() { - this.emailToLowerCase(); - } + @BeforeUpdate() + beforeUpdateActions() { + this.emailToLowerCase(); + } - @AfterLoad() - afterLoadActions() { - this.emailToLowerCase(); - } + @AfterLoad() + afterLoadActions() { + this.emailToLowerCase(); + } - private emailToLowerCase() { - if (this.invitedUserEmail) { - this.invitedUserEmail = this.invitedUserEmail.toLowerCase(); - } - } + private emailToLowerCase() { + if (this.invitedUserEmail) { + this.invitedUserEmail = this.invitedUserEmail.toLowerCase(); + } + } } diff --git a/backend/src/entities/company-info/repository/company-info-custom-repository.extension.ts b/backend/src/entities/company-info/repository/company-info-custom-repository.extension.ts index 4a12eb0ac..672ad6428 100644 --- a/backend/src/entities/company-info/repository/company-info-custom-repository.extension.ts +++ b/backend/src/entities/company-info/repository/company-info-custom-repository.extension.ts @@ -4,142 +4,142 @@ import { CompanyInfoEntity } from '../company-info.entity.js'; import { ICompanyInfoRepository } from './company-info-repository.interface.js'; export const companyInfoRepositoryExtension: ICompanyInfoRepository = { - async findCompanyInfoWithUsersById(companyId: string): Promise { - return await this.createQueryBuilder('company_info') - .leftJoinAndSelect('company_info.users', 'users') - .where('company_info.id = :companyId', { companyId }) - .getOne(); - }, + async findCompanyInfoWithUsersById(companyId: string): Promise { + return await this.createQueryBuilder('company_info') + .leftJoinAndSelect('company_info.users', 'users') + .where('company_info.id = :companyId', { companyId }) + .getOne(); + }, - async findCompanyWithInvitationsById(companyId: string): Promise { - return await this.createQueryBuilder('company_info') - .leftJoinAndSelect('company_info.invitations', 'invitations') - .where('company_info.id = :companyId', { companyId }) - .getOne(); - }, + async findCompanyWithInvitationsById(companyId: string): Promise { + return await this.createQueryBuilder('company_info') + .leftJoinAndSelect('company_info.invitations', 'invitations') + .where('company_info.id = :companyId', { companyId }) + .getOne(); + }, - async findOneCompanyInfoByUserIdWithConnections(userId: string): Promise { - return await this.createQueryBuilder('company_info') - .leftJoinAndSelect('company_info.users', 'users') - .leftJoinAndSelect('company_info.connections', 'connections') - .where('users.id = :userId', { userId }) - .getOne(); - }, + async findOneCompanyInfoByUserIdWithConnections(userId: string): Promise { + return await this.createQueryBuilder('company_info') + .leftJoinAndSelect('company_info.users', 'users') + .leftJoinAndSelect('company_info.connections', 'connections') + .where('users.id = :userId', { userId }) + .getOne(); + }, - async finOneCompanyInfoByUserId(userId: string): Promise { - return await this.createQueryBuilder('company_info') - .leftJoinAndSelect('company_info.users', 'users') - .where('users.id = :userId', { userId }) - .getOne(); - }, + async finOneCompanyInfoByUserId(userId: string): Promise { + return await this.createQueryBuilder('company_info') + .leftJoinAndSelect('company_info.users', 'users') + .where('users.id = :userId', { userId }) + .getOne(); + }, - async findCompanyInfoByUserId(userId: string): Promise { - return await this.createQueryBuilder('company_info') - .leftJoinAndSelect('company_info.users', 'users') - .where('users.id = :userId', { userId }) - .getOne(); - }, + async findCompanyInfoByUserId(userId: string): Promise { + return await this.createQueryBuilder('company_info') + .leftJoinAndSelect('company_info.users', 'users') + .where('users.id = :userId', { userId }) + .getOne(); + }, - async findUserCompanyWithUsers(userId: string): Promise { - return await this.createQueryBuilder('company_info') - .leftJoinAndSelect('company_info.users', 'current_user') - .leftJoinAndSelect('company_info.users', 'users') - .where('current_user.id = :userId', { userId }) - .getOne(); - }, + async findUserCompanyWithUsers(userId: string): Promise { + return await this.createQueryBuilder('company_info') + .leftJoinAndSelect('company_info.users', 'current_user') + .leftJoinAndSelect('company_info.users', 'users') + .where('current_user.id = :userId', { userId }) + .getOne(); + }, - async findCompanyInfoByCompanyIdWithoutConnections(companyId: string): Promise { - return await this.createQueryBuilder('company_info') - .leftJoinAndSelect('company_info.users', 'current_user') - .leftJoinAndSelect('company_info.users', 'users') - .leftJoinAndSelect('company_info.invitations', 'invitations') - .leftJoinAndSelect('company_info.logo', 'logo') - .leftJoinAndSelect('company_info.favicon', 'favicon') - .leftJoinAndSelect('company_info.tab_title', 'tab_title') - .where('company_info.id = :companyId', { companyId }) - .getOne(); - }, + async findCompanyInfoByCompanyIdWithoutConnections(companyId: string): Promise { + return await this.createQueryBuilder('company_info') + .leftJoinAndSelect('company_info.users', 'current_user') + .leftJoinAndSelect('company_info.users', 'users') + .leftJoinAndSelect('company_info.invitations', 'invitations') + .leftJoinAndSelect('company_info.logo', 'logo') + .leftJoinAndSelect('company_info.favicon', 'favicon') + .leftJoinAndSelect('company_info.tab_title', 'tab_title') + .where('company_info.id = :companyId', { companyId }) + .getOne(); + }, - // returns groups and connections where user is invited - async findFullCompanyInfoByUserId(userId: string): Promise { - return await this.createQueryBuilder('company_info') - .leftJoinAndSelect('company_info.logo', 'logo') - .leftJoinAndSelect('company_info.favicon', 'favicon') - .leftJoinAndSelect('company_info.tab_title', 'tab_title') - .leftJoinAndSelect('company_info.users', 'current_user') - .leftJoinAndSelect('company_info.users', 'users') - .leftJoinAndSelect('company_info.connections', 'connections') - .leftJoinAndSelect('company_info.invitations', 'invitations') - .leftJoinAndSelect('connections.groups', 'groups') - .leftJoinAndSelect('connections.author', 'connection_author') - .leftJoinAndSelect('groups.users', 'groups_users') - .where('current_user.id = :userId', { userId }) - .getOne(); - }, + // returns groups and connections where user is invited + async findFullCompanyInfoByUserId(userId: string): Promise { + return await this.createQueryBuilder('company_info') + .leftJoinAndSelect('company_info.logo', 'logo') + .leftJoinAndSelect('company_info.favicon', 'favicon') + .leftJoinAndSelect('company_info.tab_title', 'tab_title') + .leftJoinAndSelect('company_info.users', 'current_user') + .leftJoinAndSelect('company_info.users', 'users') + .leftJoinAndSelect('company_info.connections', 'connections') + .leftJoinAndSelect('company_info.invitations', 'invitations') + .leftJoinAndSelect('connections.groups', 'groups') + .leftJoinAndSelect('connections.author', 'connection_author') + .leftJoinAndSelect('groups.users', 'groups_users') + .where('current_user.id = :userId', { userId }) + .getOne(); + }, - async findCompanyInfosByUserEmail(userEmail: string): Promise { - return await this.createQueryBuilder('company_info') - .leftJoinAndSelect('company_info.users', 'users') - .where('users.email = :userEmail', { userEmail: userEmail?.toLowerCase() }) - .andWhere('users."externalRegistrationProvider" IS NULL') - .getMany(); - }, + async findCompanyInfosByUserEmail(userEmail: string): Promise { + return await this.createQueryBuilder('company_info') + .leftJoinAndSelect('company_info.users', 'users') + .where('users.email = :userEmail', { userEmail: userEmail?.toLowerCase() }) + .andWhere('users."externalRegistrationProvider" IS NULL') + .getMany(); + }, - async findCompaniesPaidConnections(companyIds: Array): Promise { - const paidConnectionTypes = Constants.PAID_CONNECTIONS_TYPES; - const foundCompaniesWithPaidConnections = await this.createQueryBuilder('company_info') - .leftJoinAndSelect('company_info.connections', 'connections') - .where('company_info.id IN (:...companyIds)', { companyIds }) - .andWhere('connections.type IN (:...paidConnectionTypes)', { paidConnectionTypes }) - .andWhere('connections.isTestConnection IS FALSE') - .andWhere('connections.is_frozen IS FALSE') - .getMany(); - return foundCompaniesWithPaidConnections.map((companyInfo: CompanyInfoEntity) => { - return companyInfo.connections; - }); - }, + async findCompaniesPaidConnections(companyIds: Array): Promise { + const paidConnectionTypes = Constants.PAID_CONNECTIONS_TYPES; + const foundCompaniesWithPaidConnections = await this.createQueryBuilder('company_info') + .leftJoinAndSelect('company_info.connections', 'connections') + .where('company_info.id IN (:...companyIds)', { companyIds }) + .andWhere('connections.type IN (:...paidConnectionTypes)', { paidConnectionTypes }) + .andWhere('connections.isTestConnection IS FALSE') + .andWhere('connections.is_frozen IS FALSE') + .getMany(); + return foundCompaniesWithPaidConnections.map((companyInfo: CompanyInfoEntity) => { + return companyInfo.connections; + }); + }, - async findCompanyFrozenPaidConnections(companyIds: Array): Promise> { - const paidConnectionTypes = Constants.PAID_CONNECTIONS_TYPES; - const foundCompaniesWithPaidConnections = await this.createQueryBuilder('company_info') - .leftJoinAndSelect('company_info.connections', 'connections') - .where('company_info.id IN (:...companyIds)', { companyIds }) - .andWhere('connections.type IN (:...paidConnectionTypes)', { paidConnectionTypes }) - .andWhere('connections.isTestConnection IS FALSE') - .andWhere('connections.is_frozen IS TRUE') - .getMany(); - return foundCompaniesWithPaidConnections.map((companyInfo: CompanyInfoEntity) => { - return companyInfo.connections; - }); - }, + async findCompanyFrozenPaidConnections(companyIds: Array): Promise> { + const paidConnectionTypes = Constants.PAID_CONNECTIONS_TYPES; + const foundCompaniesWithPaidConnections = await this.createQueryBuilder('company_info') + .leftJoinAndSelect('company_info.connections', 'connections') + .where('company_info.id IN (:...companyIds)', { companyIds }) + .andWhere('connections.type IN (:...paidConnectionTypes)', { paidConnectionTypes }) + .andWhere('connections.isTestConnection IS FALSE') + .andWhere('connections.is_frozen IS TRUE') + .getMany(); + return foundCompaniesWithPaidConnections.map((companyInfo: CompanyInfoEntity) => { + return companyInfo.connections; + }); + }, - async findCompanyWithLogo(companyId: string): Promise { - return await this.createQueryBuilder('company_info') - .leftJoinAndSelect('company_info.logo', 'logo') - .where('company_info.id = :companyId', { companyId }) - .getOne(); - }, + async findCompanyWithLogo(companyId: string): Promise { + return await this.createQueryBuilder('company_info') + .leftJoinAndSelect('company_info.logo', 'logo') + .where('company_info.id = :companyId', { companyId }) + .getOne(); + }, - async findCompanyWithFavicon(companyId: string): Promise { - return await this.createQueryBuilder('company_info') - .leftJoinAndSelect('company_info.favicon', 'favicon') - .where('company_info.id = :companyId', { companyId }) - .getOne(); - }, + async findCompanyWithFavicon(companyId: string): Promise { + return await this.createQueryBuilder('company_info') + .leftJoinAndSelect('company_info.favicon', 'favicon') + .where('company_info.id = :companyId', { companyId }) + .getOne(); + }, - async findCompanyWithTabTitle(companyId: string): Promise { - return await this.createQueryBuilder('company_info') - .leftJoinAndSelect('company_info.tab_title', 'tab_title') - .where('company_info.id = :companyId', { companyId }) - .getOne(); - }, + async findCompanyWithTabTitle(companyId: string): Promise { + return await this.createQueryBuilder('company_info') + .leftJoinAndSelect('company_info.tab_title', 'tab_title') + .where('company_info.id = :companyId', { companyId }) + .getOne(); + }, - async findCompanyWithWhiteLabelProperties(companyId: string): Promise { - return await this.createQueryBuilder('company_info') - .leftJoinAndSelect('company_info.logo', 'logo') - .leftJoinAndSelect('company_info.favicon', 'favicon') - .leftJoinAndSelect('company_info.tab_title', 'tab_title') - .where('company_info.id = :companyId', { companyId }) - .getOne(); - }, + async findCompanyWithWhiteLabelProperties(companyId: string): Promise { + return await this.createQueryBuilder('company_info') + .leftJoinAndSelect('company_info.logo', 'logo') + .leftJoinAndSelect('company_info.favicon', 'favicon') + .leftJoinAndSelect('company_info.tab_title', 'tab_title') + .where('company_info.id = :companyId', { companyId }) + .getOne(); + }, }; diff --git a/backend/src/entities/company-info/repository/company-info-repository.interface.ts b/backend/src/entities/company-info/repository/company-info-repository.interface.ts index 5d27ebd4f..388a8ad6d 100644 --- a/backend/src/entities/company-info/repository/company-info-repository.interface.ts +++ b/backend/src/entities/company-info/repository/company-info-repository.interface.ts @@ -2,33 +2,33 @@ import { ConnectionEntity } from '../../connection/connection.entity.js'; import { CompanyInfoEntity } from '../company-info.entity.js'; export interface ICompanyInfoRepository { - findCompanyInfoWithUsersById(companyId: string): Promise; + findCompanyInfoWithUsersById(companyId: string): Promise; - findCompanyWithInvitationsById(companyId: string): Promise; + findCompanyWithInvitationsById(companyId: string): Promise; - findOneCompanyInfoByUserIdWithConnections(userId: string): Promise; + findOneCompanyInfoByUserIdWithConnections(userId: string): Promise; - finOneCompanyInfoByUserId(userId: string): Promise; + finOneCompanyInfoByUserId(userId: string): Promise; - findCompanyInfoByUserId(userId: string): Promise; + findCompanyInfoByUserId(userId: string): Promise; - findFullCompanyInfoByUserId(userId: string): Promise; + findFullCompanyInfoByUserId(userId: string): Promise; - findCompanyInfoByCompanyIdWithoutConnections(companyId: string): Promise; + findCompanyInfoByCompanyIdWithoutConnections(companyId: string): Promise; - findCompanyInfosByUserEmail(userEmail: string): Promise; + findCompanyInfosByUserEmail(userEmail: string): Promise; - findUserCompanyWithUsers(userId: string): Promise; + findUserCompanyWithUsers(userId: string): Promise; - findCompaniesPaidConnections(companyIds: Array): Promise; + findCompaniesPaidConnections(companyIds: Array): Promise; - findCompanyFrozenPaidConnections(companyIds: Array): Promise>; + findCompanyFrozenPaidConnections(companyIds: Array): Promise>; - findCompanyWithLogo(companyId: string): Promise; + findCompanyWithLogo(companyId: string): Promise; - findCompanyWithFavicon(companyId: string): Promise; + findCompanyWithFavicon(companyId: string): Promise; - findCompanyWithTabTitle(companyId: string): Promise; + findCompanyWithTabTitle(companyId: string): Promise; - findCompanyWithWhiteLabelProperties(companyId: string): Promise; + findCompanyWithWhiteLabelProperties(companyId: string): Promise; } diff --git a/backend/src/entities/company-info/use-cases/add-company-tab-title.use.case.ts b/backend/src/entities/company-info/use-cases/add-company-tab-title.use.case.ts index 8472887dc..2f632580f 100644 --- a/backend/src/entities/company-info/use-cases/add-company-tab-title.use.case.ts +++ b/backend/src/entities/company-info/use-cases/add-company-tab-title.use.case.ts @@ -1,49 +1,49 @@ import { Inject, Injectable, NotFoundException, Scope } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; -import { AddCompanyTabTitleDs } from '../application/data-structures/add-company-tab-title.ds.js'; -import { IAddCompanyTabTitle } from './company-info-use-cases.interface.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; import { CompanyTabTitleEntity } from '../../company-tab-title/company-tab-title.entity.js'; +import { AddCompanyTabTitleDs } from '../application/data-structures/add-company-tab-title.ds.js'; +import { IAddCompanyTabTitle } from './company-info-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class AddCompanyTabTitleUseCase - extends AbstractUseCase - implements IAddCompanyTabTitle + extends AbstractUseCase + implements IAddCompanyTabTitle { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: AddCompanyTabTitleDs): Promise { - const { companyId, tab_title } = inputData; - const company = await this._dbContext.companyInfoRepository.findCompanyWithTabTitle(companyId); - if (!company) { - throw new NotFoundException(Messages.COMPANY_NOT_FOUND); - } + protected async implementation(inputData: AddCompanyTabTitleDs): Promise { + const { companyId, tab_title } = inputData; + const company = await this._dbContext.companyInfoRepository.findCompanyWithTabTitle(companyId); + if (!company) { + throw new NotFoundException(Messages.COMPANY_NOT_FOUND); + } - if (company.tab_title) { - const tabTitleForDeletion = await this._dbContext.companyTabTitleRepository.findOne({ - where: { - company: { - id: companyId, - }, - }, - }); - if (tabTitleForDeletion) { - await this._dbContext.companyTabTitleRepository.remove(tabTitleForDeletion); - } - } + if (company.tab_title) { + const tabTitleForDeletion = await this._dbContext.companyTabTitleRepository.findOne({ + where: { + company: { + id: companyId, + }, + }, + }); + if (tabTitleForDeletion) { + await this._dbContext.companyTabTitleRepository.remove(tabTitleForDeletion); + } + } - const newTabTitle = new CompanyTabTitleEntity(); - newTabTitle.company = company; - newTabTitle.text = tab_title; - await this._dbContext.companyTabTitleRepository.save(newTabTitle); - return { success: true }; - } + const newTabTitle = new CompanyTabTitleEntity(); + newTabTitle.company = company; + newTabTitle.text = tab_title; + await this._dbContext.companyTabTitleRepository.save(newTabTitle); + return { success: true }; + } } diff --git a/backend/src/entities/company-info/use-cases/check-verification-link.available.use.case.ts b/backend/src/entities/company-info/use-cases/check-verification-link.available.use.case.ts index a167802c2..50f121a41 100644 --- a/backend/src/entities/company-info/use-cases/check-verification-link.available.use.case.ts +++ b/backend/src/entities/company-info/use-cases/check-verification-link.available.use.case.ts @@ -2,9 +2,9 @@ import { Inject, Injectable } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; +import { Encryptor } from '../../../helpers/encryption/encryptor.js'; import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; import { ICheckVerificationLinkAvailable } from './company-info-use-cases.interface.js'; -import { Encryptor } from '../../../helpers/encryption/encryptor.js'; @Injectable() export class CheckIsVerificationLinkAvailable diff --git a/backend/src/entities/company-info/use-cases/company-info-use-cases.interface.ts b/backend/src/entities/company-info/use-cases/company-info-use-cases.interface.ts index 4046c1c71..e8ababec2 100644 --- a/backend/src/entities/company-info/use-cases/company-info-use-cases.interface.ts +++ b/backend/src/entities/company-info/use-cases/company-info-use-cases.interface.ts @@ -5,9 +5,9 @@ import { IToken } from '../../user/utils/generate-gwt-token.js'; import { AcceptUserValidationInCompany } from '../application/data-structures/accept-user-invitation-in-company.ds.js'; import { AddCompanyTabTitleDs } from '../application/data-structures/add-company-tab-title.ds.js'; import { - FoundUserCompanyInfoDs, - FoundUserEmailCompaniesInfoDs, - FoundUserFullCompanyInfoDs, + FoundUserCompanyInfoDs, + FoundUserEmailCompaniesInfoDs, + FoundUserFullCompanyInfoDs, } from '../application/data-structures/found-company-info.ds.js'; import { FoundCompanyNameDs } from '../application/data-structures/found-company-name.ds.js'; import { FoundCompanyTabTitleRO } from '../application/data-structures/found-company-tab-title.ro.js'; @@ -25,97 +25,97 @@ import { FoundCompanyFaviconRO, FoundCompanyLogoRO } from '../application/dto/fo import { FoundCompanyWhiteLabelPropertiesRO } from '../application/dto/found-company-white-label-properties.ro.js'; export interface IInviteUserInCompanyAndConnectionGroup { - execute(inputData: InviteUserInCompanyAndConnectionGroupDs): Promise; + execute(inputData: InviteUserInCompanyAndConnectionGroupDs): Promise; } export interface IVerifyInviteUserInCompanyAndConnectionGroup { - execute(inputData: AcceptUserValidationInCompany, inTransaction?: InTransactionEnum): Promise; + execute(inputData: AcceptUserValidationInCompany, inTransaction?: InTransactionEnum): Promise; } export interface IGetUserCompany { - execute(userId: string): Promise; + execute(userId: string): Promise; } export interface IGetCompanyName { - execute(companyId: string): Promise; + execute(companyId: string): Promise; } export interface IGetUserFullCompanyInfo { - execute(userId: string): Promise; + execute(userId: string): Promise; } export interface IGetUsersInCompany { - execute(companyId: string): Promise>; + execute(companyId: string): Promise>; } export interface IGetUserEmailCompanies { - execute(userEmail: string): Promise>; + execute(userEmail: string): Promise>; } export interface IRemoveUserFromCompany { - execute(inputData: RemoveUserFromCompanyDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: RemoveUserFromCompanyDs, inTransaction: InTransactionEnum): Promise; } export interface IRevokeUserInvitationInCompany { - execute(inputData: RevokeUserInvitationDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: RevokeUserInvitationDs, inTransaction: InTransactionEnum): Promise; } export interface IUpdateCompanyName { - execute(inputData: UpdateCompanyNameDS, inTransaction: InTransactionEnum): Promise; + execute(inputData: UpdateCompanyNameDS, inTransaction: InTransactionEnum): Promise; } export interface IUpdateUsersCompanyRoles { - execute(inputData: UpdateUsersCompanyRolesDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: UpdateUsersCompanyRolesDs, inTransaction: InTransactionEnum): Promise; } export interface IDeleteCompany { - execute(userId: string, inTransaction: InTransactionEnum): Promise; + execute(userId: string, inTransaction: InTransactionEnum): Promise; } export interface ICheckVerificationLinkAvailable { - execute(verificationString: string): Promise; + execute(verificationString: string): Promise; } export interface IUpdateUsers2faStatusInCompany { - execute(inputData: UpdateUsers2faStatusInCompanyDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: UpdateUsers2faStatusInCompanyDs, inTransaction: InTransactionEnum): Promise; } export interface ISuspendUsersInCompany { - execute(inputData: SuspendUsersInCompanyDS, inTransaction: InTransactionEnum): Promise; + execute(inputData: SuspendUsersInCompanyDS, inTransaction: InTransactionEnum): Promise; } export interface IToggleCompanyTestConnectionsMode { - execute(inputData: ToggleTestConnectionDisplayModeDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: ToggleTestConnectionDisplayModeDs, inTransaction: InTransactionEnum): Promise; } export interface IUploadCompanyWhiteLabelImages { - execute(inputData: UploadCompanyWhiteLabelImages, inTransaction: InTransactionEnum): Promise; + execute(inputData: UploadCompanyWhiteLabelImages, inTransaction: InTransactionEnum): Promise; } export interface IFindCompanyLogo { - execute(companyId: string, inTransaction: InTransactionEnum): Promise; + execute(companyId: string, inTransaction: InTransactionEnum): Promise; } export interface IFindCompanyFavicon { - execute(companyId: string, inTransaction: InTransactionEnum): Promise; + execute(companyId: string, inTransaction: InTransactionEnum): Promise; } export interface IDeleteCompanyWhiteLabelImages { - execute(companyId: string, inTransaction: InTransactionEnum): Promise; + execute(companyId: string, inTransaction: InTransactionEnum): Promise; } export interface IAddCompanyTabTitle { - execute(inputData: AddCompanyTabTitleDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: AddCompanyTabTitleDs, inTransaction: InTransactionEnum): Promise; } export interface IFindCompanyTabTitle { - execute(companyId: string, inTransaction: InTransactionEnum): Promise; + execute(companyId: string, inTransaction: InTransactionEnum): Promise; } export interface IDeleteCompanyTabTitle { - execute(companyId: string, inTransaction: InTransactionEnum): Promise; + execute(companyId: string, inTransaction: InTransactionEnum): Promise; } export interface IGetCompanyWhiteLabelProperties { - execute(companyId: string, inTransaction: InTransactionEnum): Promise; + execute(companyId: string, inTransaction: InTransactionEnum): Promise; } diff --git a/backend/src/entities/company-info/use-cases/delete-company-favicon.use.case.ts b/backend/src/entities/company-info/use-cases/delete-company-favicon.use.case.ts index a65ecd059..aa6cb50ff 100644 --- a/backend/src/entities/company-info/use-cases/delete-company-favicon.use.case.ts +++ b/backend/src/entities/company-info/use-cases/delete-company-favicon.use.case.ts @@ -1,42 +1,42 @@ import { Inject, Injectable, NotFoundException } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; -import { IDeleteCompanyWhiteLabelImages } from './company-info-use-cases.interface.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; +import { IDeleteCompanyWhiteLabelImages } from './company-info-use-cases.interface.js'; @Injectable() export class DeleteCompanyFaviconUseCase - extends AbstractUseCase - implements IDeleteCompanyWhiteLabelImages + extends AbstractUseCase + implements IDeleteCompanyWhiteLabelImages { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(companyId: string): Promise { - const company = await this._dbContext.companyInfoRepository.findCompanyWithFavicon(companyId); - if (!company) { - throw new NotFoundException(Messages.COMPANY_NOT_FOUND); - } + protected async implementation(companyId: string): Promise { + const company = await this._dbContext.companyInfoRepository.findCompanyWithFavicon(companyId); + if (!company) { + throw new NotFoundException(Messages.COMPANY_NOT_FOUND); + } - const faviconForDeletion = await this._dbContext.companyFaviconRepository.findOne({ - where: { - company: { - id: companyId, - }, - }, - }); + const faviconForDeletion = await this._dbContext.companyFaviconRepository.findOne({ + where: { + company: { + id: companyId, + }, + }, + }); - if (!faviconForDeletion) { - throw new NotFoundException(Messages.COMPANY_FAVICON_NOT_FOUND); - } + if (!faviconForDeletion) { + throw new NotFoundException(Messages.COMPANY_FAVICON_NOT_FOUND); + } - await this._dbContext.companyFaviconRepository.remove(faviconForDeletion); - return { success: true }; - } + await this._dbContext.companyFaviconRepository.remove(faviconForDeletion); + return { success: true }; + } } diff --git a/backend/src/entities/company-info/use-cases/delete-company-logo.use.case.ts b/backend/src/entities/company-info/use-cases/delete-company-logo.use.case.ts index 898ddec9a..2f7a2dd47 100644 --- a/backend/src/entities/company-info/use-cases/delete-company-logo.use.case.ts +++ b/backend/src/entities/company-info/use-cases/delete-company-logo.use.case.ts @@ -1,42 +1,42 @@ import { Inject, Injectable, NotFoundException } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; -import { IDeleteCompanyWhiteLabelImages } from './company-info-use-cases.interface.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; +import { IDeleteCompanyWhiteLabelImages } from './company-info-use-cases.interface.js'; @Injectable() export class DeleteCompanyLogoUseCase - extends AbstractUseCase - implements IDeleteCompanyWhiteLabelImages + extends AbstractUseCase + implements IDeleteCompanyWhiteLabelImages { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(companyId: string): Promise { - const company = await this._dbContext.companyInfoRepository.findCompanyWithLogo(companyId); - if (!company) { - throw new NotFoundException(Messages.COMPANY_NOT_FOUND); - } + protected async implementation(companyId: string): Promise { + const company = await this._dbContext.companyInfoRepository.findCompanyWithLogo(companyId); + if (!company) { + throw new NotFoundException(Messages.COMPANY_NOT_FOUND); + } - const logoForDeletion = await this._dbContext.companyLogoRepository.findOne({ - where: { - company: { - id: companyId, - }, - }, - }); + const logoForDeletion = await this._dbContext.companyLogoRepository.findOne({ + where: { + company: { + id: companyId, + }, + }, + }); - if (!logoForDeletion) { - throw new NotFoundException(Messages.COMPANY_LOGO_NOT_FOUND); - } + if (!logoForDeletion) { + throw new NotFoundException(Messages.COMPANY_LOGO_NOT_FOUND); + } - await this._dbContext.companyLogoRepository.remove(logoForDeletion); - return { success: true }; - } + await this._dbContext.companyLogoRepository.remove(logoForDeletion); + return { success: true }; + } } diff --git a/backend/src/entities/company-info/use-cases/delete-company-tab-title.use.case.ts b/backend/src/entities/company-info/use-cases/delete-company-tab-title.use.case.ts index 2947f8ccb..53ddb9f30 100644 --- a/backend/src/entities/company-info/use-cases/delete-company-tab-title.use.case.ts +++ b/backend/src/entities/company-info/use-cases/delete-company-tab-title.use.case.ts @@ -8,35 +8,35 @@ import { IDeleteCompanyTabTitle } from './company-info-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class DeleteCompanyTabTitleUseCase - extends AbstractUseCase - implements IDeleteCompanyTabTitle + extends AbstractUseCase + implements IDeleteCompanyTabTitle { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(companyId: string): Promise { - const company = await this._dbContext.companyInfoRepository.findCompanyWithTabTitle(companyId); - if (!company) { - throw new NotFoundException(Messages.COMPANY_NOT_FOUND); - } + protected async implementation(companyId: string): Promise { + const company = await this._dbContext.companyInfoRepository.findCompanyWithTabTitle(companyId); + if (!company) { + throw new NotFoundException(Messages.COMPANY_NOT_FOUND); + } - const tabTitleForDeletion = await this._dbContext.companyTabTitleRepository.findOne({ - where: { - company: { - id: companyId, - }, - }, - }); + const tabTitleForDeletion = await this._dbContext.companyTabTitleRepository.findOne({ + where: { + company: { + id: companyId, + }, + }, + }); - if (!tabTitleForDeletion) { - throw new NotFoundException(Messages.COMPANY_TAB_TITLE_NOT_FOUND); - } + if (!tabTitleForDeletion) { + throw new NotFoundException(Messages.COMPANY_TAB_TITLE_NOT_FOUND); + } - await this._dbContext.companyTabTitleRepository.remove(tabTitleForDeletion); - return { success: true }; - } + await this._dbContext.companyTabTitleRepository.remove(tabTitleForDeletion); + return { success: true }; + } } diff --git a/backend/src/entities/company-info/use-cases/delete-company-use-case.ts b/backend/src/entities/company-info/use-cases/delete-company-use-case.ts index a51ccb41e..13a6d67bd 100644 --- a/backend/src/entities/company-info/use-cases/delete-company-use-case.ts +++ b/backend/src/entities/company-info/use-cases/delete-company-use-case.ts @@ -2,46 +2,46 @@ import { Inject, Injectable, InternalServerErrorException, NotFoundException, Sc import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; -import { IDeleteCompany } from './company-info-use-cases.interface.js'; import { Messages } from '../../../exceptions/text/messages.js'; import { isSaaS } from '../../../helpers/app/is-saas.js'; import { SaasCompanyGatewayService } from '../../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; +import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; +import { IDeleteCompany } from './company-info-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class DeleteCompanyUseCase extends AbstractUseCase implements IDeleteCompany { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private readonly saasCompanyGatewayService: SaasCompanyGatewayService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly saasCompanyGatewayService: SaasCompanyGatewayService, + ) { + super(); + } - protected async implementation(userId: string): Promise { - const foundFullCompany = await this._dbContext.companyInfoRepository.findFullCompanyInfoByUserId(userId); - if (!foundFullCompany) { - throw new NotFoundException(Messages.COMPANY_NOT_FOUND); - } - const { users, connections, invitations, id } = foundFullCompany; - if (isSaaS()) { - const deleteResult = await this.saasCompanyGatewayService.deleteCompany(id); - if (!deleteResult) { - throw new InternalServerErrorException(Messages.SAAS_DELETE_COMPANY_FAILED_UNHANDLED_ERROR); - } - } - if (users.length) { - await this._dbContext.userRepository.remove(users); - } - if (connections.length) { - await this._dbContext.connectionRepository.remove(connections); - } - if (invitations.length) { - await this._dbContext.invitationInCompanyRepository.remove(invitations); - } - await this._dbContext.companyInfoRepository.remove(foundFullCompany); - return { - success: true, - }; - } + protected async implementation(userId: string): Promise { + const foundFullCompany = await this._dbContext.companyInfoRepository.findFullCompanyInfoByUserId(userId); + if (!foundFullCompany) { + throw new NotFoundException(Messages.COMPANY_NOT_FOUND); + } + const { users, connections, invitations, id } = foundFullCompany; + if (isSaaS()) { + const deleteResult = await this.saasCompanyGatewayService.deleteCompany(id); + if (!deleteResult) { + throw new InternalServerErrorException(Messages.SAAS_DELETE_COMPANY_FAILED_UNHANDLED_ERROR); + } + } + if (users.length) { + await this._dbContext.userRepository.remove(users); + } + if (connections.length) { + await this._dbContext.connectionRepository.remove(connections); + } + if (invitations.length) { + await this._dbContext.invitationInCompanyRepository.remove(invitations); + } + await this._dbContext.companyInfoRepository.remove(foundFullCompany); + return { + success: true, + }; + } } diff --git a/backend/src/entities/company-info/use-cases/find-company-favicon.use.case.ts b/backend/src/entities/company-info/use-cases/find-company-favicon.use.case.ts index 5ec2f29cd..c5e0cdd1a 100644 --- a/backend/src/entities/company-info/use-cases/find-company-favicon.use.case.ts +++ b/backend/src/entities/company-info/use-cases/find-company-favicon.use.case.ts @@ -8,31 +8,31 @@ import { IFindCompanyFavicon } from './company-info-use-cases.interface.js'; @Injectable() export class FindCompanyFaviconUseCase - extends AbstractUseCase - implements IFindCompanyFavicon + extends AbstractUseCase + implements IFindCompanyFavicon { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(companyId: string): Promise { - const company = await this._dbContext.companyInfoRepository.findCompanyWithFavicon(companyId); - if (!company) { - throw new NotFoundException(Messages.COMPANY_NOT_FOUND); - } - if (!company.favicon) { - return { - favicon: null, - }; - } - return { - favicon: { - image: company.favicon.image.toString('base64'), - mimeType: company.favicon.mimeType, - }, - }; - } + protected async implementation(companyId: string): Promise { + const company = await this._dbContext.companyInfoRepository.findCompanyWithFavicon(companyId); + if (!company) { + throw new NotFoundException(Messages.COMPANY_NOT_FOUND); + } + if (!company.favicon) { + return { + favicon: null, + }; + } + return { + favicon: { + image: company.favicon.image.toString('base64'), + mimeType: company.favicon.mimeType, + }, + }; + } } diff --git a/backend/src/entities/company-info/use-cases/find-company-logo.use.case.ts b/backend/src/entities/company-info/use-cases/find-company-logo.use.case.ts index 85435c75d..c4ddc3b42 100644 --- a/backend/src/entities/company-info/use-cases/find-company-logo.use.case.ts +++ b/backend/src/entities/company-info/use-cases/find-company-logo.use.case.ts @@ -1,35 +1,35 @@ import { Inject, Injectable, NotFoundException } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { IFindCompanyLogo } from './company-info-use-cases.interface.js'; -import { FoundCompanyLogoRO } from '../application/dto/found-company-logo.ro.js'; -import { BaseType } from '../../../common/data-injection.tokens.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; +import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { FoundCompanyLogoRO } from '../application/dto/found-company-logo.ro.js'; +import { IFindCompanyLogo } from './company-info-use-cases.interface.js'; @Injectable() export class FindCompanyLogoUseCase extends AbstractUseCase implements IFindCompanyLogo { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(companyId: string): Promise { - const company = await this._dbContext.companyInfoRepository.findCompanyWithLogo(companyId); - if (!company) { - throw new NotFoundException(Messages.COMPANY_NOT_FOUND); - } - if (!company.logo) { - return { - logo: null, - }; - } - return { - logo: { - image: company.logo.image.toString('base64'), - mimeType: company.logo.mimeType, - }, - }; - } + protected async implementation(companyId: string): Promise { + const company = await this._dbContext.companyInfoRepository.findCompanyWithLogo(companyId); + if (!company) { + throw new NotFoundException(Messages.COMPANY_NOT_FOUND); + } + if (!company.logo) { + return { + logo: null, + }; + } + return { + logo: { + image: company.logo.image.toString('base64'), + mimeType: company.logo.mimeType, + }, + }; + } } diff --git a/backend/src/entities/company-info/use-cases/find-company-tab-title.use.case.ts b/backend/src/entities/company-info/use-cases/find-company-tab-title.use.case.ts index b53366408..1b02a271c 100644 --- a/backend/src/entities/company-info/use-cases/find-company-tab-title.use.case.ts +++ b/backend/src/entities/company-info/use-cases/find-company-tab-title.use.case.ts @@ -8,24 +8,24 @@ import { IFindCompanyTabTitle } from './company-info-use-cases.interface.js'; @Injectable() export class FindCompanyTabTitleUseCase - extends AbstractUseCase - implements IFindCompanyTabTitle + extends AbstractUseCase + implements IFindCompanyTabTitle { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(companyId: string): Promise { - const company = await this._dbContext.companyInfoRepository.findCompanyWithTabTitle(companyId); - if (!company) { - throw new NotFoundException(Messages.COMPANY_NOT_FOUND); - } + protected async implementation(companyId: string): Promise { + const company = await this._dbContext.companyInfoRepository.findCompanyWithTabTitle(companyId); + if (!company) { + throw new NotFoundException(Messages.COMPANY_NOT_FOUND); + } - return { - tab_title: company.tab_title?.text ?? null, - }; - } + return { + tab_title: company.tab_title?.text ?? null, + }; + } } diff --git a/backend/src/entities/company-info/use-cases/find-company-white-label-properties.use.case.ts b/backend/src/entities/company-info/use-cases/find-company-white-label-properties.use.case.ts index dd3445df2..d9a4037cb 100644 --- a/backend/src/entities/company-info/use-cases/find-company-white-label-properties.use.case.ts +++ b/backend/src/entities/company-info/use-cases/find-company-white-label-properties.use.case.ts @@ -1,56 +1,56 @@ import { Inject, Injectable, NotFoundException } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { FoundCompanyWhiteLabelPropertiesRO } from '../application/dto/found-company-white-label-properties.ro.js'; -import { IGetCompanyWhiteLabelProperties } from './company-info-use-cases.interface.js'; -import { BaseType } from '../../../common/data-injection.tokens.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; +import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; import { isSaaS } from '../../../helpers/app/is-saas.js'; import { SaasCompanyGatewayService } from '../../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; +import { FoundCompanyWhiteLabelPropertiesRO } from '../application/dto/found-company-white-label-properties.ro.js'; +import { IGetCompanyWhiteLabelProperties } from './company-info-use-cases.interface.js'; @Injectable() export class FindCompanyWhiteLabelPropertiesUseCase - extends AbstractUseCase - implements IGetCompanyWhiteLabelProperties + extends AbstractUseCase + implements IGetCompanyWhiteLabelProperties { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private readonly saasCompanyGatewayService: SaasCompanyGatewayService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly saasCompanyGatewayService: SaasCompanyGatewayService, + ) { + super(); + } - protected async implementation(companyId: string): Promise { - const company = await this._dbContext.companyInfoRepository.findCompanyWithWhiteLabelProperties(companyId); - if (!company) { - throw new NotFoundException(Messages.COMPANY_NOT_FOUND); - } + protected async implementation(companyId: string): Promise { + const company = await this._dbContext.companyInfoRepository.findCompanyWithWhiteLabelProperties(companyId); + if (!company) { + throw new NotFoundException(Messages.COMPANY_NOT_FOUND); + } - let companySubscriptionLevel = null; - if (isSaaS()) { - const companyInfoFromSaas = await this.saasCompanyGatewayService.getCompanyInfo(companyId); - if (!companyInfoFromSaas) { - throw new NotFoundException(Messages.COMPANY_NOT_FOUND); - } - companySubscriptionLevel = companyInfoFromSaas.subscriptionLevel; - } + let companySubscriptionLevel = null; + if (isSaaS()) { + const companyInfoFromSaas = await this.saasCompanyGatewayService.getCompanyInfo(companyId); + if (!companyInfoFromSaas) { + throw new NotFoundException(Messages.COMPANY_NOT_FOUND); + } + companySubscriptionLevel = companyInfoFromSaas.subscriptionLevel; + } - return { - logo: company.logo - ? { - image: company.logo.image.toString('base64'), - mimeType: company.logo.mimeType, - } - : null, - favicon: company.favicon - ? { - image: company.favicon.image.toString('base64'), - mimeType: company.favicon.mimeType, - } - : null, - tab_title: company.tab_title?.text ?? null, - subscriptionLevel: companySubscriptionLevel, - }; - } + return { + logo: company.logo + ? { + image: company.logo.image.toString('base64'), + mimeType: company.logo.mimeType, + } + : null, + favicon: company.favicon + ? { + image: company.favicon.image.toString('base64'), + mimeType: company.favicon.mimeType, + } + : null, + tab_title: company.tab_title?.text ?? null, + subscriptionLevel: companySubscriptionLevel, + }; + } } diff --git a/backend/src/entities/company-info/use-cases/get-all-users-in-company.use.case.ts b/backend/src/entities/company-info/use-cases/get-all-users-in-company.use.case.ts index 17b8a10c1..ff1aca115 100644 --- a/backend/src/entities/company-info/use-cases/get-all-users-in-company.use.case.ts +++ b/backend/src/entities/company-info/use-cases/get-all-users-in-company.use.case.ts @@ -10,62 +10,62 @@ import { IGetUsersInCompany } from './company-info-use-cases.interface.js'; @Injectable() export class GetAllUsersInCompanyUseCase - extends AbstractUseCase> - implements IGetUsersInCompany + extends AbstractUseCase> + implements IGetUsersInCompany { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(companyId: string): Promise> { - const foundCompany = await this._dbContext.companyInfoRepository.findCompanyInfoWithUsersById(companyId); - if (!foundCompany) { - throw new HttpException( - { - message: Messages.COMPANY_NOT_FOUND, - }, - HttpStatus.NOT_FOUND, - ); - } - const foundUsers = foundCompany.users; + protected async implementation(companyId: string): Promise> { + const foundCompany = await this._dbContext.companyInfoRepository.findCompanyInfoWithUsersById(companyId); + if (!foundCompany) { + throw new HttpException( + { + message: Messages.COMPANY_NOT_FOUND, + }, + HttpStatus.NOT_FOUND, + ); + } + const foundUsers = foundCompany.users; - const responseObjects: Array = []; + const responseObjects: Array = []; - const queue = new PQueue({ concurrency: 3 }); - await Promise.all( - foundUsers.map(async (user) => { - await queue.add(async () => { - if (!user) { - return; - } - const usersConnectionsWithGroups = await this._dbContext.connectionRepository.findAllUserNonTestsConnections( - user.id, - ); - const userInfo = buildSimpleUserInfoDs(user); - const userRO: SimpleFoundUserInCompanyInfoDs = { - ...userInfo, - user_membership: usersConnectionsWithGroups.map((connection) => { - return { - id: connection.id, - title: connection.title, - database: connection.database, - groups: connection.groups.map((group) => { - return { - id: group.id, - title: group.title, - }; - }), - }; - }), - has_groups: usersConnectionsWithGroups.length > 0, - }; - responseObjects.push(userRO); - }); - }), - ); - return responseObjects; - } + const queue = new PQueue({ concurrency: 3 }); + await Promise.all( + foundUsers.map(async (user) => { + await queue.add(async () => { + if (!user) { + return; + } + const usersConnectionsWithGroups = await this._dbContext.connectionRepository.findAllUserNonTestsConnections( + user.id, + ); + const userInfo = buildSimpleUserInfoDs(user); + const userRO: SimpleFoundUserInCompanyInfoDs = { + ...userInfo, + user_membership: usersConnectionsWithGroups.map((connection) => { + return { + id: connection.id, + title: connection.title, + database: connection.database, + groups: connection.groups.map((group) => { + return { + id: group.id, + title: group.title, + }; + }), + }; + }), + has_groups: usersConnectionsWithGroups.length > 0, + }; + responseObjects.push(userRO); + }); + }), + ); + return responseObjects; + } } diff --git a/backend/src/entities/company-info/use-cases/get-company-name.use.case.ts b/backend/src/entities/company-info/use-cases/get-company-name.use.case.ts index 4f4370693..0c7cf75d5 100644 --- a/backend/src/entities/company-info/use-cases/get-company-name.use.case.ts +++ b/backend/src/entities/company-info/use-cases/get-company-name.use.case.ts @@ -1,33 +1,33 @@ import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; -import { IGetCompanyName } from './company-info-use-cases.interface.js'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { FoundCompanyNameDs } from '../application/data-structures/found-company-name.ds.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { FoundCompanyNameDs } from '../application/data-structures/found-company-name.ds.js'; +import { IGetCompanyName } from './company-info-use-cases.interface.js'; @Injectable() export class GetCompanyNameUseCase extends AbstractUseCase implements IGetCompanyName { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: string): Promise { - const foundCompany = await this._dbContext.companyInfoRepository.findOneBy({ id: inputData }); - if (!foundCompany) { - throw new HttpException( - { - message: Messages.COMPANY_NOT_FOUND, - }, - HttpStatus.NOT_FOUND, - ); - } - return { - id: foundCompany.id, - name: foundCompany.name, - }; - } + protected async implementation(inputData: string): Promise { + const foundCompany = await this._dbContext.companyInfoRepository.findOneBy({ id: inputData }); + if (!foundCompany) { + throw new HttpException( + { + message: Messages.COMPANY_NOT_FOUND, + }, + HttpStatus.NOT_FOUND, + ); + } + return { + id: foundCompany.id, + name: foundCompany.name, + }; + } } diff --git a/backend/src/entities/company-info/use-cases/get-full-user-company-info.use.case.ts b/backend/src/entities/company-info/use-cases/get-full-user-company-info.use.case.ts index 7d4a14c36..be009ae8c 100644 --- a/backend/src/entities/company-info/use-cases/get-full-user-company-info.use.case.ts +++ b/backend/src/entities/company-info/use-cases/get-full-user-company-info.use.case.ts @@ -7,8 +7,8 @@ import { isSaaS } from '../../../helpers/app/is-saas.js'; import { SaasCompanyGatewayService } from '../../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; import { UserRoleEnum } from '../../user/enums/user-role.enum.js'; import { - FoundUserCompanyInfoDs, - FoundUserFullCompanyInfoDs, + FoundUserCompanyInfoDs, + FoundUserFullCompanyInfoDs, } from '../application/data-structures/found-company-info.ds.js'; import { CompanyInfoEntity } from '../company-info.entity.js'; import { buildFoundCompanyFullInfoDs, buildFoundCompanyInfoDs } from '../utils/build-found-company-info-ds.js'; @@ -16,86 +16,86 @@ import { IGetUserFullCompanyInfo } from './company-info-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class GetUserCompanyFullInfoUseCase - extends AbstractUseCase - implements IGetUserFullCompanyInfo + extends AbstractUseCase + implements IGetUserFullCompanyInfo { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private readonly saasCompanyGatewayService: SaasCompanyGatewayService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly saasCompanyGatewayService: SaasCompanyGatewayService, + ) { + super(); + } - protected async implementation(userId: string): Promise { - const foundCompanyInfoByUserId = await this._dbContext.companyInfoRepository.findCompanyInfoByUserId(userId); + protected async implementation(userId: string): Promise { + const foundCompanyInfoByUserId = await this._dbContext.companyInfoRepository.findCompanyInfoByUserId(userId); - if (!foundCompanyInfoByUserId) { - throw new HttpException( - { - message: Messages.COMPANY_NOT_FOUND, - }, - HttpStatus.NOT_FOUND, - ); - } + if (!foundCompanyInfoByUserId) { + throw new HttpException( + { + message: Messages.COMPANY_NOT_FOUND, + }, + HttpStatus.NOT_FOUND, + ); + } - const foundUser = await this._dbContext.userRepository.findOneUserByIdAndCompanyId( - userId, - foundCompanyInfoByUserId.id, - ); + const foundUser = await this._dbContext.userRepository.findOneUserByIdAndCompanyId( + userId, + foundCompanyInfoByUserId.id, + ); - const foundFullUserCoreCompanyInfo: CompanyInfoEntity = - await this._dbContext.companyInfoRepository.findFullCompanyInfoByUserId(userId); + const foundFullUserCoreCompanyInfo: CompanyInfoEntity = + await this._dbContext.companyInfoRepository.findFullCompanyInfoByUserId(userId); - //todo deprecated code, will be removed in future - // if (foundUser.role === UserRoleEnum.ADMIN) { + //todo deprecated code, will be removed in future + // if (foundUser.role === UserRoleEnum.ADMIN) { - // const companyId = foundCompanyInfoByUserId.id; + // const companyId = foundCompanyInfoByUserId.id; - // const [companyInfoWithoutConnections, companyInfoWithUsers] = await Promise.all([ - // this._dbContext.companyInfoRepository.findCompanyInfoByCompanyIdWithoutConnections(companyId), - // this._dbContext.companyInfoRepository.findAllCompanyWithConnectionsUsersJoining(companyId), - // ]); + // const [companyInfoWithoutConnections, companyInfoWithUsers] = await Promise.all([ + // this._dbContext.companyInfoRepository.findCompanyInfoByCompanyIdWithoutConnections(companyId), + // this._dbContext.companyInfoRepository.findAllCompanyWithConnectionsUsersJoining(companyId), + // ]); - // const uniqueConnections = companyInfoWithUsers.users - // .flatMap((user) => user.groups.map((group) => group.connection)) - // .filter((connection, index, self) => index === self.findIndex((t) => t.id === connection.id)); + // const uniqueConnections = companyInfoWithUsers.users + // .flatMap((user) => user.groups.map((group) => group.connection)) + // .filter((connection, index, self) => index === self.findIndex((t) => t.id === connection.id)); - // companyInfoWithoutConnections.connections = uniqueConnections; - // foundFullUserCoreCompanyInfo = companyInfoWithoutConnections; - // console.log( - // '🚀 ~ GetUserCompanyFullInfoUseCase ~ implementation ~ foundFullUserCoreCompanyInfo:', - // foundFullUserCoreCompanyInfo, - // ); - // } else { - // foundFullUserCoreCompanyInfo = await this._dbContext.companyInfoRepository.findFullCompanyInfoByUserId(userId); - // } + // companyInfoWithoutConnections.connections = uniqueConnections; + // foundFullUserCoreCompanyInfo = companyInfoWithoutConnections; + // console.log( + // '🚀 ~ GetUserCompanyFullInfoUseCase ~ implementation ~ foundFullUserCoreCompanyInfo:', + // foundFullUserCoreCompanyInfo, + // ); + // } else { + // foundFullUserCoreCompanyInfo = await this._dbContext.companyInfoRepository.findFullCompanyInfoByUserId(userId); + // } - let foundUserCompanySaasInfo = null; + let foundUserCompanySaasInfo = null; - let customDomain = null; - if (isSaaS()) { - foundUserCompanySaasInfo = await this.saasCompanyGatewayService.getCompanyInfo(foundFullUserCoreCompanyInfo.id); - if (!foundUserCompanySaasInfo) { - throw new HttpException( - { - message: Messages.COMPANY_NOT_FOUND, - }, - HttpStatus.NOT_FOUND, - ); - } - customDomain = await this.saasCompanyGatewayService.getCompanyCustomDomainById(foundCompanyInfoByUserId.id); - } + let customDomain = null; + if (isSaaS()) { + foundUserCompanySaasInfo = await this.saasCompanyGatewayService.getCompanyInfo(foundFullUserCoreCompanyInfo.id); + if (!foundUserCompanySaasInfo) { + throw new HttpException( + { + message: Messages.COMPANY_NOT_FOUND, + }, + HttpStatus.NOT_FOUND, + ); + } + customDomain = await this.saasCompanyGatewayService.getCompanyCustomDomainById(foundCompanyInfoByUserId.id); + } - if (foundUser.role === UserRoleEnum.ADMIN) { - return buildFoundCompanyFullInfoDs( - foundFullUserCoreCompanyInfo, - foundUserCompanySaasInfo, - foundUser.role, - customDomain, - ); - } + if (foundUser.role === UserRoleEnum.ADMIN) { + return buildFoundCompanyFullInfoDs( + foundFullUserCoreCompanyInfo, + foundUserCompanySaasInfo, + foundUser.role, + customDomain, + ); + } - return buildFoundCompanyInfoDs(foundFullUserCoreCompanyInfo, foundUserCompanySaasInfo, customDomain); - } + return buildFoundCompanyInfoDs(foundFullUserCoreCompanyInfo, foundUserCompanySaasInfo, customDomain); + } } diff --git a/backend/src/entities/company-info/use-cases/get-user-company.use.case.ts b/backend/src/entities/company-info/use-cases/get-user-company.use.case.ts index 4f476a722..fd589e52f 100644 --- a/backend/src/entities/company-info/use-cases/get-user-company.use.case.ts +++ b/backend/src/entities/company-info/use-cases/get-user-company.use.case.ts @@ -2,49 +2,49 @@ import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import { SaasCompanyGatewayService } from '../../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; -import { IGetUserCompany } from './company-info-use-cases.interface.js'; import { Messages } from '../../../exceptions/text/messages.js'; import { isSaaS } from '../../../helpers/app/is-saas.js'; +import { SaasCompanyGatewayService } from '../../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; import { FoundUserCompanyInfoDs } from '../application/data-structures/found-company-info.ds.js'; import { buildFoundCompanyInfoDs } from '../utils/build-found-company-info-ds.js'; +import { IGetUserCompany } from './company-info-use-cases.interface.js'; @Injectable() export class GetUserCompanyUseCase extends AbstractUseCase implements IGetUserCompany { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private readonly saasCompanyGatewayService: SaasCompanyGatewayService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly saasCompanyGatewayService: SaasCompanyGatewayService, + ) { + super(); + } - protected async implementation(userId: string): Promise { - const foundUserCoreCompanyInfo = await this._dbContext.companyInfoRepository.findCompanyInfoByUserId(userId); + protected async implementation(userId: string): Promise { + const foundUserCoreCompanyInfo = await this._dbContext.companyInfoRepository.findCompanyInfoByUserId(userId); - if (!foundUserCoreCompanyInfo) { - throw new HttpException( - { - message: Messages.COMPANY_NOT_FOUND, - }, - HttpStatus.NOT_FOUND, - ); - } + if (!foundUserCoreCompanyInfo) { + throw new HttpException( + { + message: Messages.COMPANY_NOT_FOUND, + }, + HttpStatus.NOT_FOUND, + ); + } - let foundUserCompanySaasInfo = null; - let customDomain = null; - if (isSaaS()) { - foundUserCompanySaasInfo = await this.saasCompanyGatewayService.getCompanyInfo(foundUserCoreCompanyInfo.id); - if (!foundUserCompanySaasInfo) { - throw new HttpException( - { - message: Messages.COMPANY_NOT_FOUND, - }, - HttpStatus.NOT_FOUND, - ); - } - customDomain = await this.saasCompanyGatewayService.getCompanyCustomDomainById(foundUserCoreCompanyInfo.id); - } - return buildFoundCompanyInfoDs(foundUserCoreCompanyInfo, foundUserCompanySaasInfo, customDomain); - } + let foundUserCompanySaasInfo = null; + let customDomain = null; + if (isSaaS()) { + foundUserCompanySaasInfo = await this.saasCompanyGatewayService.getCompanyInfo(foundUserCoreCompanyInfo.id); + if (!foundUserCompanySaasInfo) { + throw new HttpException( + { + message: Messages.COMPANY_NOT_FOUND, + }, + HttpStatus.NOT_FOUND, + ); + } + customDomain = await this.saasCompanyGatewayService.getCompanyCustomDomainById(foundUserCoreCompanyInfo.id); + } + return buildFoundCompanyInfoDs(foundUserCoreCompanyInfo, foundUserCompanySaasInfo, customDomain); + } } diff --git a/backend/src/entities/company-info/use-cases/get-user-email-companies.use.case.ts b/backend/src/entities/company-info/use-cases/get-user-email-companies.use.case.ts index 342b46bbe..ca95e63eb 100644 --- a/backend/src/entities/company-info/use-cases/get-user-email-companies.use.case.ts +++ b/backend/src/entities/company-info/use-cases/get-user-email-companies.use.case.ts @@ -8,33 +8,33 @@ import { IGetUserEmailCompanies } from './company-info-use-cases.interface.js'; @Injectable() export class GetUserEmailCompaniesUseCase - extends AbstractUseCase> - implements IGetUserEmailCompanies + extends AbstractUseCase> + implements IGetUserEmailCompanies { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(userEmail: string): Promise> { - const useEmailCompaniesInfosFromCore = await this._dbContext.companyInfoRepository.findCompanyInfosByUserEmail( - userEmail.toLowerCase(), - ); - if (!useEmailCompaniesInfosFromCore.length) { - throw new HttpException( - { - message: Messages.COMPANIES_USER_EMAIL_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - return useEmailCompaniesInfosFromCore.map(({ id, name }) => { - return { - id, - name, - }; - }); - } + protected async implementation(userEmail: string): Promise> { + const useEmailCompaniesInfosFromCore = await this._dbContext.companyInfoRepository.findCompanyInfosByUserEmail( + userEmail.toLowerCase(), + ); + if (!useEmailCompaniesInfosFromCore.length) { + throw new HttpException( + { + message: Messages.COMPANIES_USER_EMAIL_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + return useEmailCompaniesInfosFromCore.map(({ id, name }) => { + return { + id, + name, + }; + }); + } } diff --git a/backend/src/entities/company-info/use-cases/invite-user-in-company.use.case.ts b/backend/src/entities/company-info/use-cases/invite-user-in-company.use.case.ts index d447486fb..60253ee48 100644 --- a/backend/src/entities/company-info/use-cases/invite-user-in-company.use.case.ts +++ b/backend/src/entities/company-info/use-cases/invite-user-in-company.use.case.ts @@ -1,17 +1,17 @@ -import { Injectable, Inject, HttpException, HttpStatus, Scope } from '@nestjs/common'; +import { HttpException, HttpStatus, Inject, Injectable, Scope } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import { InviteUserInCompanyAndConnectionGroupDs } from '../application/data-structures/invite-user-in-company-and-connection-group.ds.js'; -import { IInviteUserInCompanyAndConnectionGroup } from './company-info-use-cases.interface.js'; -import { InvitedUserInCompanyAndConnectionGroupDs } from '../application/data-structures/invited-user-in-company-and-connection-group.ds.js'; import { Messages } from '../../../exceptions/text/messages.js'; import { isSaaS } from '../../../helpers/app/is-saas.js'; -import { SaasCompanyGatewayService } from '../../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; import { isTest } from '../../../helpers/app/is-test.js'; +import { SaasCompanyGatewayService } from '../../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; import { EmailService } from '../../email/email/email.service.js'; -import { CompanyInfoHelperService } from '../company-info-helper.service.js'; import { WinstonLogger } from '../../logging/winston-logger.js'; +import { InviteUserInCompanyAndConnectionGroupDs } from '../application/data-structures/invite-user-in-company-and-connection-group.ds.js'; +import { InvitedUserInCompanyAndConnectionGroupDs } from '../application/data-structures/invited-user-in-company-and-connection-group.ds.js'; +import { CompanyInfoHelperService } from '../company-info-helper.service.js'; +import { IInviteUserInCompanyAndConnectionGroup } from './company-info-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class InviteUserInCompanyAndConnectionGroupUseCase diff --git a/backend/src/entities/company-info/use-cases/remove-user-from-company.use.case.ts b/backend/src/entities/company-info/use-cases/remove-user-from-company.use.case.ts index b4cfe6324..d79fb0990 100644 --- a/backend/src/entities/company-info/use-cases/remove-user-from-company.use.case.ts +++ b/backend/src/entities/company-info/use-cases/remove-user-from-company.use.case.ts @@ -3,58 +3,58 @@ import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { SaasCompanyGatewayService } from '../../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; import { RemoveUserFromCompanyDs } from '../application/data-structures/remove-user-from-company.ds.js'; import { IRemoveUserFromCompany } from './company-info-use-cases.interface.js'; -import { SaasCompanyGatewayService } from '../../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; @Injectable({ scope: Scope.REQUEST }) export class RemoveUserFromCompanyUseCase - extends AbstractUseCase - implements IRemoveUserFromCompany + extends AbstractUseCase + implements IRemoveUserFromCompany { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private readonly saasCompanyGatewayService: SaasCompanyGatewayService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly saasCompanyGatewayService: SaasCompanyGatewayService, + ) { + super(); + } - protected async implementation(inputData: RemoveUserFromCompanyDs): Promise { - const { companyId, userId } = inputData; - const foundCompanyWithUsers = await this._dbContext.companyInfoRepository.findCompanyInfoWithUsersById(companyId); - if (!foundCompanyWithUsers) { - throw new HttpException( - { - message: Messages.COMPANY_NOT_FOUND, - }, - HttpStatus.NOT_FOUND, - ); - } - if (foundCompanyWithUsers.users.length === 1) { - throw new HttpException( - { - message: Messages.CANT_REMOVE_LAST_USER_FROM_COMPANY, - }, - HttpStatus.BAD_REQUEST, - ); - } - const foundUser = foundCompanyWithUsers.users.find((user) => user.id === userId); - if (!foundUser) { - throw new HttpException( - { - message: Messages.USER_NOT_FOUND, - }, - HttpStatus.NOT_FOUND, - ); - } - foundCompanyWithUsers.users = foundCompanyWithUsers.users.filter((user) => user.id !== userId); - await this._dbContext.companyInfoRepository.save(foundCompanyWithUsers); - await this._dbContext.userRepository.remove(foundUser); - await this.saasCompanyGatewayService.recountUsersInCompanyRequest(companyId); - return { - success: true, - }; - } + protected async implementation(inputData: RemoveUserFromCompanyDs): Promise { + const { companyId, userId } = inputData; + const foundCompanyWithUsers = await this._dbContext.companyInfoRepository.findCompanyInfoWithUsersById(companyId); + if (!foundCompanyWithUsers) { + throw new HttpException( + { + message: Messages.COMPANY_NOT_FOUND, + }, + HttpStatus.NOT_FOUND, + ); + } + if (foundCompanyWithUsers.users.length === 1) { + throw new HttpException( + { + message: Messages.CANT_REMOVE_LAST_USER_FROM_COMPANY, + }, + HttpStatus.BAD_REQUEST, + ); + } + const foundUser = foundCompanyWithUsers.users.find((user) => user.id === userId); + if (!foundUser) { + throw new HttpException( + { + message: Messages.USER_NOT_FOUND, + }, + HttpStatus.NOT_FOUND, + ); + } + foundCompanyWithUsers.users = foundCompanyWithUsers.users.filter((user) => user.id !== userId); + await this._dbContext.companyInfoRepository.save(foundCompanyWithUsers); + await this._dbContext.userRepository.remove(foundUser); + await this.saasCompanyGatewayService.recountUsersInCompanyRequest(companyId); + return { + success: true, + }; + } } diff --git a/backend/src/entities/company-info/use-cases/revoke-invitation-in-company.use.case.ts b/backend/src/entities/company-info/use-cases/revoke-invitation-in-company.use.case.ts index 2391fac9b..d800b8856 100644 --- a/backend/src/entities/company-info/use-cases/revoke-invitation-in-company.use.case.ts +++ b/backend/src/entities/company-info/use-cases/revoke-invitation-in-company.use.case.ts @@ -9,47 +9,47 @@ import { IRevokeUserInvitationInCompany } from './company-info-use-cases.interfa @Injectable({ scope: Scope.REQUEST }) export class RevokeUserInvitationInCompanyUseCase - extends AbstractUseCase - implements IRevokeUserInvitationInCompany + extends AbstractUseCase + implements IRevokeUserInvitationInCompany { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: RevokeUserInvitationDs): Promise { - const { companyId } = inputData; - const email = inputData.email.toLowerCase(); - const foundCompanyWithInvitations = - await this._dbContext.companyInfoRepository.findCompanyWithInvitationsById(companyId); - if (!foundCompanyWithInvitations) { - throw new HttpException( - { - message: Messages.COMPANY_NOT_FOUND, - }, - HttpStatus.NOT_FOUND, - ); - } - const foundInvitation = foundCompanyWithInvitations.invitations.find( - (invitation) => invitation.invitedUserEmail === email, - ); - if (!foundInvitation) { - throw new HttpException( - { - message: Messages.NOTHING_TO_REVOKE, - }, - HttpStatus.NOT_FOUND, - ); - } - foundCompanyWithInvitations.invitations = foundCompanyWithInvitations.invitations.filter( - (invitation) => invitation.invitedUserEmail !== email, - ); - await this._dbContext.companyInfoRepository.save(foundCompanyWithInvitations); - await this._dbContext.invitationInCompanyRepository.remove(foundInvitation); - return { - success: true, - }; - } + protected async implementation(inputData: RevokeUserInvitationDs): Promise { + const { companyId } = inputData; + const email = inputData.email.toLowerCase(); + const foundCompanyWithInvitations = + await this._dbContext.companyInfoRepository.findCompanyWithInvitationsById(companyId); + if (!foundCompanyWithInvitations) { + throw new HttpException( + { + message: Messages.COMPANY_NOT_FOUND, + }, + HttpStatus.NOT_FOUND, + ); + } + const foundInvitation = foundCompanyWithInvitations.invitations.find( + (invitation) => invitation.invitedUserEmail === email, + ); + if (!foundInvitation) { + throw new HttpException( + { + message: Messages.NOTHING_TO_REVOKE, + }, + HttpStatus.NOT_FOUND, + ); + } + foundCompanyWithInvitations.invitations = foundCompanyWithInvitations.invitations.filter( + (invitation) => invitation.invitedUserEmail !== email, + ); + await this._dbContext.companyInfoRepository.save(foundCompanyWithInvitations); + await this._dbContext.invitationInCompanyRepository.remove(foundInvitation); + return { + success: true, + }; + } } diff --git a/backend/src/entities/company-info/use-cases/suspend-users-in-company.use.case.ts b/backend/src/entities/company-info/use-cases/suspend-users-in-company.use.case.ts index 876796a2a..fd570627a 100644 --- a/backend/src/entities/company-info/use-cases/suspend-users-in-company.use.case.ts +++ b/backend/src/entities/company-info/use-cases/suspend-users-in-company.use.case.ts @@ -9,40 +9,40 @@ import { ISuspendUsersInCompany } from './company-info-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class SuspendUsersInCompanyUseCase - extends AbstractUseCase - implements ISuspendUsersInCompany + extends AbstractUseCase + implements ISuspendUsersInCompany { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: SuspendUsersInCompanyDS): Promise { - const { companyInfoId } = inputData; - const usersEmails = inputData.usersEmails.map((email) => email.toLowerCase()); - const foundCompany = await this._dbContext.companyInfoRepository.findCompanyInfoWithUsersById(companyInfoId); - if (!foundCompany) { - throw new NotFoundException(Messages.COMPANY_NOT_FOUND); - } - const userIdsToSuspend = foundCompany.users - .filter((user) => usersEmails.includes(user.email.toLowerCase())) - .map((user) => user.id); + protected async implementation(inputData: SuspendUsersInCompanyDS): Promise { + const { companyInfoId } = inputData; + const usersEmails = inputData.usersEmails.map((email) => email.toLowerCase()); + const foundCompany = await this._dbContext.companyInfoRepository.findCompanyInfoWithUsersById(companyInfoId); + if (!foundCompany) { + throw new NotFoundException(Messages.COMPANY_NOT_FOUND); + } + const userIdsToSuspend = foundCompany.users + .filter((user) => usersEmails.includes(user.email.toLowerCase())) + .map((user) => user.id); - if (!userIdsToSuspend.length) { - throw new BadRequestException(Messages.NO_USERS_TO_SUSPEND); - } + if (!userIdsToSuspend.length) { + throw new BadRequestException(Messages.NO_USERS_TO_SUSPEND); + } - const currentUnsuspendUsersInCompany = foundCompany.users.filter((user) => !user.suspended); - const isUnsuspendUserLeft = currentUnsuspendUsersInCompany.length - userIdsToSuspend.length <= 0; + const currentUnsuspendUsersInCompany = foundCompany.users.filter((user) => !user.suspended); + const isUnsuspendUserLeft = currentUnsuspendUsersInCompany.length - userIdsToSuspend.length <= 0; - if (isUnsuspendUserLeft) { - throw new BadRequestException(Messages.CANNOT_SUSPEND_LAST_USER); - } - await this._dbContext.userRepository.suspendUsers(userIdsToSuspend); - return { - success: true, - }; - } + if (isUnsuspendUserLeft) { + throw new BadRequestException(Messages.CANNOT_SUSPEND_LAST_USER); + } + await this._dbContext.userRepository.suspendUsers(userIdsToSuspend); + return { + success: true, + }; + } } diff --git a/backend/src/entities/company-info/use-cases/toggle-test-connections-company-display-mode.use.case.ts b/backend/src/entities/company-info/use-cases/toggle-test-connections-company-display-mode.use.case.ts index 177a82691..ce2705f68 100644 --- a/backend/src/entities/company-info/use-cases/toggle-test-connections-company-display-mode.use.case.ts +++ b/backend/src/entities/company-info/use-cases/toggle-test-connections-company-display-mode.use.case.ts @@ -1,36 +1,36 @@ import { Inject, Injectable, NotFoundException, Scope } from '@nestjs/common'; +import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; -import { ToggleTestConnectionDisplayModeDs } from '../application/data-structures/toggle-test-connections-display-mode.ds.js'; -import { IToggleCompanyTestConnectionsMode } from './company-info-use-cases.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; +import { ToggleTestConnectionDisplayModeDs } from '../application/data-structures/toggle-test-connections-display-mode.ds.js'; +import { IToggleCompanyTestConnectionsMode } from './company-info-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class ToggleCompanyTestConnectionsDisplayModeUseCase - extends AbstractUseCase - implements IToggleCompanyTestConnectionsMode + extends AbstractUseCase + implements IToggleCompanyTestConnectionsMode { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - public async implementation(inputData: ToggleTestConnectionDisplayModeDs): Promise { - const { userId, displayMode } = inputData; - const foundCompanyInfo = await this._dbContext.companyInfoRepository.finOneCompanyInfoByUserId(userId); - if (!foundCompanyInfo) { - throw new NotFoundException(Messages.COMPANY_NOT_FOUND); - } + public async implementation(inputData: ToggleTestConnectionDisplayModeDs): Promise { + const { userId, displayMode } = inputData; + const foundCompanyInfo = await this._dbContext.companyInfoRepository.finOneCompanyInfoByUserId(userId); + if (!foundCompanyInfo) { + throw new NotFoundException(Messages.COMPANY_NOT_FOUND); + } - const companyToUpdate = await this._dbContext.companyInfoRepository.findOne({ where: { id: foundCompanyInfo.id } }); - companyToUpdate.show_test_connections = displayMode; - await this._dbContext.companyInfoRepository.save(companyToUpdate); - return { - success: true, - }; - } + const companyToUpdate = await this._dbContext.companyInfoRepository.findOne({ where: { id: foundCompanyInfo.id } }); + companyToUpdate.show_test_connections = displayMode; + await this._dbContext.companyInfoRepository.save(companyToUpdate); + return { + success: true, + }; + } } diff --git a/backend/src/entities/company-info/use-cases/unsuspend-users-in-company.use.case.ts b/backend/src/entities/company-info/use-cases/unsuspend-users-in-company.use.case.ts index c7441c565..c4634a772 100644 --- a/backend/src/entities/company-info/use-cases/unsuspend-users-in-company.use.case.ts +++ b/backend/src/entities/company-info/use-cases/unsuspend-users-in-company.use.case.ts @@ -1,11 +1,11 @@ import { - BadRequestException, - HttpException, - HttpStatus, - Inject, - Injectable, - NotFoundException, - Scope, + BadRequestException, + HttpException, + HttpStatus, + Inject, + Injectable, + NotFoundException, + Scope, } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; @@ -19,46 +19,46 @@ import { ISuspendUsersInCompany } from './company-info-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class UnsuspendUsersInCompanyUseCase - extends AbstractUseCase - implements ISuspendUsersInCompany + extends AbstractUseCase + implements ISuspendUsersInCompany { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private readonly companyInfoHelperService: CompanyInfoHelperService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly companyInfoHelperService: CompanyInfoHelperService, + ) { + super(); + } - protected async implementation(inputData: SuspendUsersInCompanyDS): Promise { - const { companyInfoId } = inputData; - const usersEmails = inputData.usersEmails.map((email) => email.toLowerCase()); - const foundCompany = await this._dbContext.companyInfoRepository.findCompanyInfoWithUsersById(companyInfoId); - if (!foundCompany) { - throw new NotFoundException(Messages.COMPANY_NOT_FOUND); - } - const userIdsToSuspend = foundCompany.users - .filter((user) => usersEmails.includes(user.email.toLowerCase())) - .map((user) => user.id); + protected async implementation(inputData: SuspendUsersInCompanyDS): Promise { + const { companyInfoId } = inputData; + const usersEmails = inputData.usersEmails.map((email) => email.toLowerCase()); + const foundCompany = await this._dbContext.companyInfoRepository.findCompanyInfoWithUsersById(companyInfoId); + if (!foundCompany) { + throw new NotFoundException(Messages.COMPANY_NOT_FOUND); + } + const userIdsToSuspend = foundCompany.users + .filter((user) => usersEmails.includes(user.email.toLowerCase())) + .map((user) => user.id); - if (!userIdsToSuspend.length) { - throw new BadRequestException(Messages.NO_USERS_TO_SUSPEND); - } + if (!userIdsToSuspend.length) { + throw new BadRequestException(Messages.NO_USERS_TO_SUSPEND); + } - if (isSaaS()) { - const canInviteMoreUsers = await this.companyInfoHelperService.canInviteMoreUsers(companyInfoId); - if (!canInviteMoreUsers && foundCompany.users?.length > 3) { - throw new HttpException( - { - message: Messages.CANT_UNSUSPEND_USERS_FREE_PLAN, - }, - HttpStatus.BAD_REQUEST, - ); - } - } - await this._dbContext.userRepository.unSuspendUsers(userIdsToSuspend); - return { - success: true, - }; - } + if (isSaaS()) { + const canInviteMoreUsers = await this.companyInfoHelperService.canInviteMoreUsers(companyInfoId); + if (!canInviteMoreUsers && foundCompany.users?.length > 3) { + throw new HttpException( + { + message: Messages.CANT_UNSUSPEND_USERS_FREE_PLAN, + }, + HttpStatus.BAD_REQUEST, + ); + } + } + await this._dbContext.userRepository.unSuspendUsers(userIdsToSuspend); + return { + success: true, + }; + } } diff --git a/backend/src/entities/company-info/use-cases/update-company-name.use.case.ts b/backend/src/entities/company-info/use-cases/update-company-name.use.case.ts index eb310445f..e74669b68 100644 --- a/backend/src/entities/company-info/use-cases/update-company-name.use.case.ts +++ b/backend/src/entities/company-info/use-cases/update-company-name.use.case.ts @@ -8,23 +8,23 @@ import { IUpdateCompanyName } from './company-info-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class UpdateCompanyNameUseCase - extends AbstractUseCase - implements IUpdateCompanyName + extends AbstractUseCase + implements IUpdateCompanyName { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: UpdateCompanyNameDS): Promise { - const { companyId, name } = inputData; - const foundCompany = await this._dbContext.companyInfoRepository.findOneBy({ id: companyId }); - foundCompany.name = name; - await this._dbContext.companyInfoRepository.save(foundCompany); - return { - success: true, - }; - } + protected async implementation(inputData: UpdateCompanyNameDS): Promise { + const { companyId, name } = inputData; + const foundCompany = await this._dbContext.companyInfoRepository.findOneBy({ id: companyId }); + foundCompany.name = name; + await this._dbContext.companyInfoRepository.save(foundCompany); + return { + success: true, + }; + } } diff --git a/backend/src/entities/company-info/use-cases/update-users-company-roles.use.case.ts b/backend/src/entities/company-info/use-cases/update-users-company-roles.use.case.ts index c3c28aacb..3a613302b 100644 --- a/backend/src/entities/company-info/use-cases/update-users-company-roles.use.case.ts +++ b/backend/src/entities/company-info/use-cases/update-users-company-roles.use.case.ts @@ -11,70 +11,70 @@ import { IUpdateUsersCompanyRoles } from './company-info-use-cases.interface.js' @Injectable({ scope: Scope.REQUEST }) export class UpdateUsersCompanyRolesUseCase - extends AbstractUseCase - implements IUpdateUsersCompanyRoles + extends AbstractUseCase + implements IUpdateUsersCompanyRoles { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: UpdateUsersCompanyRolesDs): Promise { - const { companyId, users } = inputData; - const foundCompanyWithUsers = await this._dbContext.companyInfoRepository.findCompanyInfoWithUsersById(companyId); - if (!foundCompanyWithUsers) { - throw new HttpException( - { - message: Messages.COMPANY_NOT_FOUND, - }, - HttpStatus.NOT_FOUND, - ); - } + protected async implementation(inputData: UpdateUsersCompanyRolesDs): Promise { + const { companyId, users } = inputData; + const foundCompanyWithUsers = await this._dbContext.companyInfoRepository.findCompanyInfoWithUsersById(companyId); + if (!foundCompanyWithUsers) { + throw new HttpException( + { + message: Messages.COMPANY_NOT_FOUND, + }, + HttpStatus.NOT_FOUND, + ); + } - const companyUsersToUpdate: Array = foundCompanyWithUsers.users.filter( - (userInCompany) => !!users.find((userFromReceivedUsers) => userFromReceivedUsers.userId === userInCompany.id), - ); + const companyUsersToUpdate: Array = foundCompanyWithUsers.users.filter( + (userInCompany) => !!users.find((userFromReceivedUsers) => userFromReceivedUsers.userId === userInCompany.id), + ); - if (companyUsersToUpdate.length === 0) { - throw new HttpException( - { - message: Messages.NO_USERS_FOUND_TO_UPDATE_ROLES, - }, - HttpStatus.NOT_FOUND, - ); - } + if (companyUsersToUpdate.length === 0) { + throw new HttpException( + { + message: Messages.NO_USERS_FOUND_TO_UPDATE_ROLES, + }, + HttpStatus.NOT_FOUND, + ); + } - const companyUsersToUpdateIds: Array = companyUsersToUpdate.map((user) => user.id); + const companyUsersToUpdateIds: Array = companyUsersToUpdate.map((user) => user.id); - const clearUsersWithNewRoles: Array<{ userId: string; role: UserRoleEnum }> = companyUsersToUpdateIds.map( - (userId) => { - return { - userId: userId, - role: users.find((user) => user.userId === userId).role, - }; - }, - ); + const clearUsersWithNewRoles: Array<{ userId: string; role: UserRoleEnum }> = companyUsersToUpdateIds.map( + (userId) => { + return { + userId: userId, + role: users.find((user) => user.userId === userId).role, + }; + }, + ); - const usersWithUpdatedRoles = companyUsersToUpdate.map((user) => { - const newUserRole = clearUsersWithNewRoles.find((userWithNewRole) => userWithNewRole.userId === user.id).role; - user.role = newUserRole; - return user; - }); + const usersWithUpdatedRoles = companyUsersToUpdate.map((user) => { + const newUserRole = clearUsersWithNewRoles.find((userWithNewRole) => userWithNewRole.userId === user.id).role; + user.role = newUserRole; + return user; + }); - try { - await this._dbContext.userRepository.bulkSaveUpdatedUsers(usersWithUpdatedRoles); - return { - success: true, - }; - } catch (_e) { - throw new HttpException( - { - message: Messages.USER_ROLES_UPDATE_FAILED, - }, - HttpStatus.INTERNAL_SERVER_ERROR, - ); - } - } + try { + await this._dbContext.userRepository.bulkSaveUpdatedUsers(usersWithUpdatedRoles); + return { + success: true, + }; + } catch (_e) { + throw new HttpException( + { + message: Messages.USER_ROLES_UPDATE_FAILED, + }, + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } } diff --git a/backend/src/entities/company-info/use-cases/update-uses-2fa-status-in-company.use.case.ts b/backend/src/entities/company-info/use-cases/update-uses-2fa-status-in-company.use.case.ts index ec0c3bdf9..5c0c7c04e 100644 --- a/backend/src/entities/company-info/use-cases/update-uses-2fa-status-in-company.use.case.ts +++ b/backend/src/entities/company-info/use-cases/update-uses-2fa-status-in-company.use.case.ts @@ -10,29 +10,29 @@ import { IUpdateUsers2faStatusInCompany } from './company-info-use-cases.interfa @Injectable({ scope: Scope.REQUEST }) export class UpdateUses2faStatusInCompanyUseCase - extends AbstractUseCase - implements IUpdateUsers2faStatusInCompany + extends AbstractUseCase + implements IUpdateUsers2faStatusInCompany { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private readonly emailService: EmailService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly emailService: EmailService, + ) { + super(); + } - protected async implementation(inputData: UpdateUsers2faStatusInCompanyDs): Promise { - const { companyId, is2faEnabled } = inputData; - const foundCompany = await this._dbContext.companyInfoRepository.findCompanyInfoWithUsersById(companyId); - if (!foundCompany) { - throw new NotFoundException(Messages.COMPANY_NOT_FOUND); - } - foundCompany.is2faEnabled = is2faEnabled; - if (is2faEnabled) { - const usersEmails = foundCompany.users.map((user) => user.email.toLowerCase()); - this.emailService.send2faEnabledInCompany(usersEmails, foundCompany.name); - } - await this._dbContext.companyInfoRepository.save(foundCompany); - return { success: true }; - } + protected async implementation(inputData: UpdateUsers2faStatusInCompanyDs): Promise { + const { companyId, is2faEnabled } = inputData; + const foundCompany = await this._dbContext.companyInfoRepository.findCompanyInfoWithUsersById(companyId); + if (!foundCompany) { + throw new NotFoundException(Messages.COMPANY_NOT_FOUND); + } + foundCompany.is2faEnabled = is2faEnabled; + if (is2faEnabled) { + const usersEmails = foundCompany.users.map((user) => user.email.toLowerCase()); + this.emailService.send2faEnabledInCompany(usersEmails, foundCompany.name); + } + await this._dbContext.companyInfoRepository.save(foundCompany); + return { success: true }; + } } diff --git a/backend/src/entities/company-info/use-cases/upload-company-favicon.use.case.ts b/backend/src/entities/company-info/use-cases/upload-company-favicon.use.case.ts index 722f95a0f..208db85fc 100644 --- a/backend/src/entities/company-info/use-cases/upload-company-favicon.use.case.ts +++ b/backend/src/entities/company-info/use-cases/upload-company-favicon.use.case.ts @@ -10,41 +10,41 @@ import { IUploadCompanyWhiteLabelImages } from './company-info-use-cases.interfa @Injectable({ scope: Scope.REQUEST }) export class UploadCompanyFaviconUseCase - extends AbstractUseCase - implements IUploadCompanyWhiteLabelImages + extends AbstractUseCase + implements IUploadCompanyWhiteLabelImages { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: UploadCompanyWhiteLabelImages): Promise { - const { companyId, file } = inputData; - const company = await this._dbContext.companyInfoRepository.findCompanyWithFavicon(companyId); - if (!company) { - throw new NotFoundException(Messages.COMPANY_NOT_FOUND); - } + protected async implementation(inputData: UploadCompanyWhiteLabelImages): Promise { + const { companyId, file } = inputData; + const company = await this._dbContext.companyInfoRepository.findCompanyWithFavicon(companyId); + if (!company) { + throw new NotFoundException(Messages.COMPANY_NOT_FOUND); + } - if (company.favicon) { - const faviconForDeletion = await this._dbContext.companyFaviconRepository.findOne({ - where: { - company: { - id: companyId, - }, - }, - }); - if (faviconForDeletion) { - await this._dbContext.companyFaviconRepository.remove(faviconForDeletion); - } - } + if (company.favicon) { + const faviconForDeletion = await this._dbContext.companyFaviconRepository.findOne({ + where: { + company: { + id: companyId, + }, + }, + }); + if (faviconForDeletion) { + await this._dbContext.companyFaviconRepository.remove(faviconForDeletion); + } + } - const newFavicon = new CompanyFaviconEntity(); - newFavicon.company = company; - newFavicon.image = file.buffer; - newFavicon.mimeType = file.mimetype; - await this._dbContext.companyFaviconRepository.save(newFavicon); - return { success: true }; - } + const newFavicon = new CompanyFaviconEntity(); + newFavicon.company = company; + newFavicon.image = file.buffer; + newFavicon.mimeType = file.mimetype; + await this._dbContext.companyFaviconRepository.save(newFavicon); + return { success: true }; + } } diff --git a/backend/src/entities/company-info/use-cases/upload-company-logo-use-case.ts b/backend/src/entities/company-info/use-cases/upload-company-logo-use-case.ts index 162e6aef0..8ecb38c6f 100644 --- a/backend/src/entities/company-info/use-cases/upload-company-logo-use-case.ts +++ b/backend/src/entities/company-info/use-cases/upload-company-logo-use-case.ts @@ -1,50 +1,50 @@ import { Inject, Injectable, NotFoundException, Scope } from '@nestjs/common'; -import { IUploadCompanyWhiteLabelImages } from './company-info-use-cases.interface.js'; -import { UploadCompanyWhiteLabelImages } from '../application/data-structures/upload-company-white-label-images.ds.js'; -import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; import { CompanyLogoEntity } from '../../company-logo/company-logo.entity.js'; +import { UploadCompanyWhiteLabelImages } from '../application/data-structures/upload-company-white-label-images.ds.js'; +import { IUploadCompanyWhiteLabelImages } from './company-info-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class UploadCompanyLogoUseCase - extends AbstractUseCase - implements IUploadCompanyWhiteLabelImages + extends AbstractUseCase + implements IUploadCompanyWhiteLabelImages { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: UploadCompanyWhiteLabelImages): Promise { - const { companyId, file } = inputData; - const company = await this._dbContext.companyInfoRepository.findCompanyWithLogo(companyId); - if (!company) { - throw new NotFoundException(Messages.COMPANY_NOT_FOUND); - } + protected async implementation(inputData: UploadCompanyWhiteLabelImages): Promise { + const { companyId, file } = inputData; + const company = await this._dbContext.companyInfoRepository.findCompanyWithLogo(companyId); + if (!company) { + throw new NotFoundException(Messages.COMPANY_NOT_FOUND); + } - if (company.logo) { - const logoForDeletion = await this._dbContext.companyLogoRepository.findOne({ - where: { - company: { - id: companyId, - }, - }, - }); - if (logoForDeletion) { - await this._dbContext.companyLogoRepository.remove(logoForDeletion); - } - } + if (company.logo) { + const logoForDeletion = await this._dbContext.companyLogoRepository.findOne({ + where: { + company: { + id: companyId, + }, + }, + }); + if (logoForDeletion) { + await this._dbContext.companyLogoRepository.remove(logoForDeletion); + } + } - const newLogo = new CompanyLogoEntity(); - newLogo.company = company; - newLogo.image = file.buffer; - newLogo.mimeType = file.mimetype; - await this._dbContext.companyLogoRepository.save(newLogo); - return { success: true }; - } + const newLogo = new CompanyLogoEntity(); + newLogo.company = company; + newLogo.image = file.buffer; + newLogo.mimeType = file.mimetype; + await this._dbContext.companyLogoRepository.save(newLogo); + return { success: true }; + } } diff --git a/backend/src/entities/company-info/use-cases/verify-invite-user-in-company.use.case.ts b/backend/src/entities/company-info/use-cases/verify-invite-user-in-company.use.case.ts index ca755f978..bfb1e7ca6 100644 --- a/backend/src/entities/company-info/use-cases/verify-invite-user-in-company.use.case.ts +++ b/backend/src/entities/company-info/use-cases/verify-invite-user-in-company.use.case.ts @@ -3,12 +3,12 @@ import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; -import { IToken, generateGwtToken } from '../../user/utils/generate-gwt-token.js'; +import { Encryptor } from '../../../helpers/encryption/encryptor.js'; +import { SaasCompanyGatewayService } from '../../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; +import { generateGwtToken, IToken } from '../../user/utils/generate-gwt-token.js'; import { get2FaScope } from '../../user/utils/is-jwt-scope-need.util.js'; import { AcceptUserValidationInCompany } from '../application/data-structures/accept-user-invitation-in-company.ds.js'; import { IVerifyInviteUserInCompanyAndConnectionGroup } from './company-info-use-cases.interface.js'; -import { SaasCompanyGatewayService } from '../../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; -import { Encryptor } from '../../../helpers/encryption/encryptor.js'; @Injectable({ scope: Scope.REQUEST }) export class VerifyInviteUserInCompanyAndConnectionGroupUseCase diff --git a/backend/src/entities/company-info/utils/build-found-company-info-ds.ts b/backend/src/entities/company-info/utils/build-found-company-info-ds.ts index 06f2ebb04..d4a1450a5 100644 --- a/backend/src/entities/company-info/utils/build-found-company-info-ds.ts +++ b/backend/src/entities/company-info/utils/build-found-company-info-ds.ts @@ -3,109 +3,109 @@ import { FoundSipleConnectionInfoDS } from '../../connection/application/data-st import { UserRoleEnum } from '../../user/enums/user-role.enum.js'; import { buildSimpleUserInfoDs } from '../../user/utils/build-created-user.ds.js'; import { - FoundUserCompanyInfoDs, - FoundUserFullCompanyInfoDs, + FoundUserCompanyInfoDs, + FoundUserFullCompanyInfoDs, } from '../application/data-structures/found-company-info.ds.js'; import { FoundInvitationInCompanyDs } from '../application/data-structures/found-invitation-in-company.ds.js'; import { CompanyInfoEntity } from '../company-info.entity.js'; export function buildFoundCompanyFullInfoDs( - companyInfoFromCore: CompanyInfoEntity, - companyInfoFromSaas: FoundSassCompanyInfoDS | null, - userRole: UserRoleEnum, - companyCustomDomain: string | null, + companyInfoFromCore: CompanyInfoEntity, + companyInfoFromSaas: FoundSassCompanyInfoDS | null, + userRole: UserRoleEnum, + companyCustomDomain: string | null, ): FoundUserFullCompanyInfoDs { - if (!companyInfoFromCore.show_test_connections) { - companyInfoFromCore.connections = companyInfoFromCore.connections.filter( - (connection) => !connection.isTestConnection, - ); - } - const responseObject = buildFoundCompanyInfoDs( - companyInfoFromCore, - companyInfoFromSaas, - companyCustomDomain, - userRole, - ) as any; - const connectionsRO: Array = companyInfoFromCore.connections.map((connection) => { - return { - id: connection.id, - createdAt: connection.createdAt, - updatedAt: connection.updatedAt, - title: connection.title, - isTestConnection: connection.isTestConnection, - author: buildSimpleUserInfoDs(connection.author), - groups: connection.groups.map((group) => { - return { - id: group.id, - isMain: group.isMain, - title: group.title, - users: group.users.map((user) => buildSimpleUserInfoDs(user)).filter((user) => !!user), - }; - }), - }; - }); - responseObject.connections = connectionsRO; - const invitationsRO: Array = companyInfoFromCore.invitations.map((invitation) => { - return { - id: invitation.id, - verification_string: invitation.verification_string, - groupId: invitation.groupId, - inviterId: invitation.inviterId, - invitedUserEmail: invitation.invitedUserEmail, - role: invitation.role, - createdAt: invitation.createdAt, - }; - }); - responseObject.invitations = invitationsRO; - return responseObject; + if (!companyInfoFromCore.show_test_connections) { + companyInfoFromCore.connections = companyInfoFromCore.connections.filter( + (connection) => !connection.isTestConnection, + ); + } + const responseObject = buildFoundCompanyInfoDs( + companyInfoFromCore, + companyInfoFromSaas, + companyCustomDomain, + userRole, + ) as any; + const connectionsRO: Array = companyInfoFromCore.connections.map((connection) => { + return { + id: connection.id, + createdAt: connection.createdAt, + updatedAt: connection.updatedAt, + title: connection.title, + isTestConnection: connection.isTestConnection, + author: buildSimpleUserInfoDs(connection.author), + groups: connection.groups.map((group) => { + return { + id: group.id, + isMain: group.isMain, + title: group.title, + users: group.users.map((user) => buildSimpleUserInfoDs(user)).filter((user) => !!user), + }; + }), + }; + }); + responseObject.connections = connectionsRO; + const invitationsRO: Array = companyInfoFromCore.invitations.map((invitation) => { + return { + id: invitation.id, + verification_string: invitation.verification_string, + groupId: invitation.groupId, + inviterId: invitation.inviterId, + invitedUserEmail: invitation.invitedUserEmail, + role: invitation.role, + createdAt: invitation.createdAt, + }; + }); + responseObject.invitations = invitationsRO; + return responseObject; } export function buildFoundCompanyInfoDs( - companyInfoFromCore: CompanyInfoEntity, - companyInfoFromSaas: FoundSassCompanyInfoDS | null, - companyCustomDomain: string, - userRole?: UserRoleEnum, + companyInfoFromCore: CompanyInfoEntity, + companyInfoFromSaas: FoundSassCompanyInfoDS | null, + companyCustomDomain: string, + userRole?: UserRoleEnum, ): FoundUserCompanyInfoDs { - if (!companyInfoFromSaas) { - return { - id: companyInfoFromCore.id, - name: companyInfoFromCore.name, - is2faEnabled: companyInfoFromCore.is2faEnabled, - show_test_connections: companyInfoFromCore.show_test_connections, - custom_domain: companyCustomDomain ? companyCustomDomain : null, - logo: companyInfoFromCore.logo - ? { - image: companyInfoFromCore.logo.image.toString('base64'), - mimeType: companyInfoFromCore.logo.mimeType, - } - : null, - favicon: companyInfoFromCore.favicon - ? { - image: companyInfoFromCore.favicon.image.toString('base64'), - mimeType: companyInfoFromCore.favicon.mimeType, - } - : null, - tab_title: companyInfoFromCore.tab_title?.text ?? null, - }; - } - const isUserAdmin = userRole === UserRoleEnum.ADMIN; - return { - id: companyInfoFromCore.id, - name: companyInfoFromCore.name, - portal_link: isUserAdmin ? companyInfoFromSaas.portal_link : undefined, - subscriptionLevel: companyInfoFromSaas.subscriptionLevel, - is_payment_method_added: isUserAdmin ? companyInfoFromSaas.is_payment_method_added : undefined, - is2faEnabled: isUserAdmin ? companyInfoFromCore.is2faEnabled : undefined, - show_test_connections: companyInfoFromCore.show_test_connections, - custom_domain: companyCustomDomain ? companyCustomDomain : null, - logo: companyInfoFromCore.logo - ? { image: companyInfoFromCore.logo.image.toString('base64'), mimeType: companyInfoFromCore.logo.mimeType } - : null, - favicon: companyInfoFromCore.favicon - ? { image: companyInfoFromCore.favicon.image.toString('base64'), mimeType: companyInfoFromCore.favicon.mimeType } - : null, - tab_title: companyInfoFromCore.tab_title?.text ?? null, - createdAt: companyInfoFromSaas.createdAt, - updatedAt: companyInfoFromSaas.updatedAt, - }; + if (!companyInfoFromSaas) { + return { + id: companyInfoFromCore.id, + name: companyInfoFromCore.name, + is2faEnabled: companyInfoFromCore.is2faEnabled, + show_test_connections: companyInfoFromCore.show_test_connections, + custom_domain: companyCustomDomain ? companyCustomDomain : null, + logo: companyInfoFromCore.logo + ? { + image: companyInfoFromCore.logo.image.toString('base64'), + mimeType: companyInfoFromCore.logo.mimeType, + } + : null, + favicon: companyInfoFromCore.favicon + ? { + image: companyInfoFromCore.favicon.image.toString('base64'), + mimeType: companyInfoFromCore.favicon.mimeType, + } + : null, + tab_title: companyInfoFromCore.tab_title?.text ?? null, + }; + } + const isUserAdmin = userRole === UserRoleEnum.ADMIN; + return { + id: companyInfoFromCore.id, + name: companyInfoFromCore.name, + portal_link: isUserAdmin ? companyInfoFromSaas.portal_link : undefined, + subscriptionLevel: companyInfoFromSaas.subscriptionLevel, + is_payment_method_added: isUserAdmin ? companyInfoFromSaas.is_payment_method_added : undefined, + is2faEnabled: isUserAdmin ? companyInfoFromCore.is2faEnabled : undefined, + show_test_connections: companyInfoFromCore.show_test_connections, + custom_domain: companyCustomDomain ? companyCustomDomain : null, + logo: companyInfoFromCore.logo + ? { image: companyInfoFromCore.logo.image.toString('base64'), mimeType: companyInfoFromCore.logo.mimeType } + : null, + favicon: companyInfoFromCore.favicon + ? { image: companyInfoFromCore.favicon.image.toString('base64'), mimeType: companyInfoFromCore.favicon.mimeType } + : null, + tab_title: companyInfoFromCore.tab_title?.text ?? null, + createdAt: companyInfoFromSaas.createdAt, + updatedAt: companyInfoFromSaas.updatedAt, + }; } diff --git a/backend/src/entities/company-info/utils/get-company-name.ts b/backend/src/entities/company-info/utils/get-company-name.ts index 5caf555fb..0858a3a36 100644 --- a/backend/src/entities/company-info/utils/get-company-name.ts +++ b/backend/src/entities/company-info/utils/get-company-name.ts @@ -1,3 +1,3 @@ export function generateCompanyName(): string { - return `DEFAULT_COMPANY`; + return `DEFAULT_COMPANY`; } diff --git a/backend/src/entities/company-logo/company-logo.entity.ts b/backend/src/entities/company-logo/company-logo.entity.ts index 2876dd369..803cd83b1 100644 --- a/backend/src/entities/company-logo/company-logo.entity.ts +++ b/backend/src/entities/company-logo/company-logo.entity.ts @@ -3,21 +3,25 @@ import { CompanyInfoEntity } from '../company-info/company-info.entity.js'; @Entity('company_logo') export class CompanyLogoEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ type: 'bytea', nullable: true }) - image: Buffer; + @Column({ type: 'bytea', nullable: true }) + image: Buffer; - @Column({ type: 'varchar', length: 24, nullable: false, default: 'image/png' }) - mimeType: string; + @Column({ type: 'varchar', length: 24, nullable: false, default: 'image/png' }) + mimeType: string; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - createdAt: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + createdAt: Date; - @OneToOne((_) => CompanyInfoEntity, (company) => company.logo, { - onDelete: 'CASCADE', - }) - @JoinColumn() - company: Relation; + @OneToOne( + (_) => CompanyInfoEntity, + (company) => company.logo, + { + onDelete: 'CASCADE', + }, + ) + @JoinColumn() + company: Relation; } diff --git a/backend/src/entities/company-logo/company-logo.module.ts b/backend/src/entities/company-logo/company-logo.module.ts index b105e7a51..04ad82aa8 100644 --- a/backend/src/entities/company-logo/company-logo.module.ts +++ b/backend/src/entities/company-logo/company-logo.module.ts @@ -4,8 +4,8 @@ import { CompanyInfoEntity } from '../company-info/company-info.entity.js'; import { CompanyLogoEntity } from './company-logo.entity.js'; @Module({ - imports: [TypeOrmModule.forFeature([CompanyInfoEntity, CompanyLogoEntity])], - providers: [], - exports: [], + imports: [TypeOrmModule.forFeature([CompanyInfoEntity, CompanyLogoEntity])], + providers: [], + exports: [], }) export class CompanyLogoModule {} diff --git a/backend/src/entities/company-tab-title/company-tab-title.entity.ts b/backend/src/entities/company-tab-title/company-tab-title.entity.ts index 0ba93896b..821df6099 100644 --- a/backend/src/entities/company-tab-title/company-tab-title.entity.ts +++ b/backend/src/entities/company-tab-title/company-tab-title.entity.ts @@ -3,18 +3,22 @@ import { CompanyInfoEntity } from '../company-info/company-info.entity.js'; @Entity('company_tab_title') export class CompanyTabTitleEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ type: 'varchar', length: 255, unique: false, nullable: true }) - text: string; + @Column({ type: 'varchar', length: 255, unique: false, nullable: true }) + text: string; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - createdAt: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + createdAt: Date; - @OneToOne((_) => CompanyInfoEntity, (company) => company.tab_title, { - onDelete: 'CASCADE', - }) - @JoinColumn() - company: Relation; + @OneToOne( + (_) => CompanyInfoEntity, + (company) => company.tab_title, + { + onDelete: 'CASCADE', + }, + ) + @JoinColumn() + company: Relation; } diff --git a/backend/src/entities/company-tab-title/company-tab-title.module.ts b/backend/src/entities/company-tab-title/company-tab-title.module.ts index abc1fcf59..3efadca81 100644 --- a/backend/src/entities/company-tab-title/company-tab-title.module.ts +++ b/backend/src/entities/company-tab-title/company-tab-title.module.ts @@ -4,8 +4,8 @@ import { CompanyInfoEntity } from '../company-info/company-info.entity.js'; import { CompanyTabTitleEntity } from './company-tab-title.entity.js'; @Module({ - imports: [TypeOrmModule.forFeature([CompanyInfoEntity, CompanyTabTitleEntity])], - providers: [], - exports: [], + imports: [TypeOrmModule.forFeature([CompanyInfoEntity, CompanyTabTitleEntity])], + providers: [], + exports: [], }) export class CompanyTabTitleModule {} diff --git a/backend/src/entities/connection-properties/application/data-structures/create-connection-properties.ds.ts b/backend/src/entities/connection-properties/application/data-structures/create-connection-properties.ds.ts index 0bdd6a5a4..06d670ef3 100644 --- a/backend/src/entities/connection-properties/application/data-structures/create-connection-properties.ds.ts +++ b/backend/src/entities/connection-properties/application/data-structures/create-connection-properties.ds.ts @@ -1,21 +1,21 @@ export class CreateConnectionPropertiesDs { - hidden_tables: Array; - userId: string; - connectionId: string; - master_password: string; - logo_url: string; - primary_color: string; - secondary_color: string; - hostname: string; - company_name: string; - tables_audit: boolean; - human_readable_table_names: boolean; - allow_ai_requests: boolean; - default_showing_table: string; - table_categories: Array<{ - category_name: string; - tables: Array; - category_color: string; - category_id: string; - }>; + hidden_tables: Array; + userId: string; + connectionId: string; + master_password: string; + logo_url: string; + primary_color: string; + secondary_color: string; + hostname: string; + company_name: string; + tables_audit: boolean; + human_readable_table_names: boolean; + allow_ai_requests: boolean; + default_showing_table: string; + table_categories: Array<{ + category_name: string; + tables: Array; + category_color: string; + category_id: string; + }>; } diff --git a/backend/src/entities/connection-properties/application/data-structures/found-connection-properties.ds.ts b/backend/src/entities/connection-properties/application/data-structures/found-connection-properties.ds.ts index 227cb7cf5..799d8cc6a 100644 --- a/backend/src/entities/connection-properties/application/data-structures/found-connection-properties.ds.ts +++ b/backend/src/entities/connection-properties/application/data-structures/found-connection-properties.ds.ts @@ -2,42 +2,42 @@ import { ApiProperty } from '@nestjs/swagger'; import { FoundTableCategoryRo } from '../../../table-categories/dto/found-table-category.ro.js'; export class FoundConnectionPropertiesDs { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty({ isArray: true, type: String }) - hidden_tables: Array; + @ApiProperty({ isArray: true, type: String }) + hidden_tables: Array; - @ApiProperty() - connectionId: string; + @ApiProperty() + connectionId: string; - @ApiProperty() - logo_url: string; + @ApiProperty() + logo_url: string; - @ApiProperty() - primary_color: string; + @ApiProperty() + primary_color: string; - @ApiProperty() - secondary_color: string; + @ApiProperty() + secondary_color: string; - @ApiProperty() - hostname: string; + @ApiProperty() + hostname: string; - @ApiProperty() - company_name: string; + @ApiProperty() + company_name: string; - @ApiProperty() - tables_audit: boolean; + @ApiProperty() + tables_audit: boolean; - @ApiProperty() - human_readable_table_names: boolean; + @ApiProperty() + human_readable_table_names: boolean; - @ApiProperty() - allow_ai_requests: boolean; + @ApiProperty() + allow_ai_requests: boolean; - @ApiProperty() - default_showing_table: string; + @ApiProperty() + default_showing_table: string; - @ApiProperty({ isArray: true }) - table_categories: Array; + @ApiProperty({ isArray: true }) + table_categories: Array; } diff --git a/backend/src/entities/connection-properties/connection-properties.controller.ts b/backend/src/entities/connection-properties/connection-properties.controller.ts index 98c5c3141..d04b930c4 100644 --- a/backend/src/entities/connection-properties/connection-properties.controller.ts +++ b/backend/src/entities/connection-properties/connection-properties.controller.ts @@ -15,6 +15,7 @@ import { HttpException } from '@nestjs/common/exceptions/http.exception.js'; import { ApiBearerAuth, ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import { UseCaseType } from '../../common/data-injection.tokens.js'; import { MasterPassword, SlugUuid, UserId } from '../../decorators/index.js'; +import { Timeout } from '../../decorators/timeout.decorator.js'; import { InTransactionEnum } from '../../enums/index.js'; import { Messages } from '../../exceptions/text/messages.js'; import { ConnectionEditGuard, ConnectionReadGuard } from '../../guards/index.js'; @@ -29,7 +30,6 @@ import { IFindConnectionProperties, IUpdateConnectionProperties, } from './use-cases/connection-properties-use.cases.interface.js'; -import { Timeout } from '../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/connection-properties/connection-properties.entity.ts b/backend/src/entities/connection-properties/connection-properties.entity.ts index 8645043bf..c1d349c6e 100644 --- a/backend/src/entities/connection-properties/connection-properties.entity.ts +++ b/backend/src/entities/connection-properties/connection-properties.entity.ts @@ -4,45 +4,52 @@ import { TableCategoriesEntity } from '../table-categories/table-categories.enti @Entity('connectionProperties') export class ConnectionPropertiesEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column('varchar', { array: true, default: null }) - hidden_tables: string[]; + @Column('varchar', { array: true, default: null }) + hidden_tables: string[]; - @Column({ default: null }) - logo_url: string; + @Column({ default: null }) + logo_url: string; - @Column({ default: '' }) - primary_color: string; + @Column({ default: '' }) + primary_color: string; - @Column({ default: '' }) - secondary_color: string; + @Column({ default: '' }) + secondary_color: string; - @Column({ default: null }) - hostname: string; + @Column({ default: null }) + hostname: string; - @Column({ default: null }) - company_name: string; + @Column({ default: null }) + company_name: string; - @Column({ default: true, type: 'boolean' }) - tables_audit: boolean; + @Column({ default: true, type: 'boolean' }) + tables_audit: boolean; - @Column({ default: true, type: 'boolean' }) - human_readable_table_names: boolean; + @Column({ default: true, type: 'boolean' }) + human_readable_table_names: boolean; - @Column({ default: true, type: 'boolean' }) - allow_ai_requests: boolean; + @Column({ default: true, type: 'boolean' }) + allow_ai_requests: boolean; - @Column({ default: null }) - default_showing_table: string; + @Column({ default: null }) + default_showing_table: string; - @OneToOne((_) => ConnectionEntity, (connection) => connection.connection_properties, { - onDelete: 'CASCADE', - }) - @JoinColumn() - connection: Relation; + @OneToOne( + (_) => ConnectionEntity, + (connection) => connection.connection_properties, + { + onDelete: 'CASCADE', + }, + ) + @JoinColumn() + connection: Relation; - @OneToMany(() => TableCategoriesEntity, (table_categories) => table_categories.connection_properties) - table_categories: Relation; + @OneToMany( + () => TableCategoriesEntity, + (table_categories) => table_categories.connection_properties, + ) + table_categories: Relation; } diff --git a/backend/src/entities/connection-properties/connection-properties.interface.ts b/backend/src/entities/connection-properties/connection-properties.interface.ts index 9903d6f53..7b6b8506c 100644 --- a/backend/src/entities/connection-properties/connection-properties.interface.ts +++ b/backend/src/entities/connection-properties/connection-properties.interface.ts @@ -1,5 +1,5 @@ export interface IConnectionPropertiesRO { - id: string; - hidden_tables: Array; - connectionId: string; + id: string; + hidden_tables: Array; + connectionId: string; } diff --git a/backend/src/entities/connection-properties/connection-properties.module.ts b/backend/src/entities/connection-properties/connection-properties.module.ts index 128133acc..74bf566fb 100644 --- a/backend/src/entities/connection-properties/connection-properties.module.ts +++ b/backend/src/entities/connection-properties/connection-properties.module.ts @@ -14,37 +14,45 @@ import { FindConnectionPropertiesUseCase } from './use-cases/find-connection-pro import { UpdateConnectionPropertiesUseCase } from './use-cases/update-connection-properties.use.case.js'; @Module({ - imports: [TypeOrmModule.forFeature([ConnectionEntity, ConnectionPropertiesEntity, UserEntity, LogOutEntity])], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.FIND_CONNECTION_PROPERTIES, - useClass: FindConnectionPropertiesUseCase, - }, - { - provide: UseCaseType.CREATE_CONNECTION_PROPERTIES, - useClass: CreateConnectionPropertiesUseCase, - }, - { - provide: UseCaseType.UPDATE_CONNECTION_PROPERTIES, - useClass: UpdateConnectionPropertiesUseCase, - }, - { - provide: UseCaseType.DELETE_CONNECTION_PROPERTIES, - useClass: DeleteConnectionPropertiesUseCase, - }, - ], - controllers: [ConnectionPropertiesController], - exports: [], + imports: [TypeOrmModule.forFeature([ConnectionEntity, ConnectionPropertiesEntity, UserEntity, LogOutEntity])], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.FIND_CONNECTION_PROPERTIES, + useClass: FindConnectionPropertiesUseCase, + }, + { + provide: UseCaseType.CREATE_CONNECTION_PROPERTIES, + useClass: CreateConnectionPropertiesUseCase, + }, + { + provide: UseCaseType.UPDATE_CONNECTION_PROPERTIES, + useClass: UpdateConnectionPropertiesUseCase, + }, + { + provide: UseCaseType.DELETE_CONNECTION_PROPERTIES, + useClass: DeleteConnectionPropertiesUseCase, + }, + ], + controllers: [ConnectionPropertiesController], + exports: [], }) export class ConnectionPropertiesModule implements NestModule { - public configure(consumer: MiddlewareConsumer): void { - consumer.apply(AuthMiddleware).forRoutes({ path: '/connection/properties/:connectionId', method: RequestMethod.GET }); - consumer.apply(AuthMiddleware).forRoutes({ path: '/connection/properties/:connectionId', method: RequestMethod.POST }); - consumer.apply(AuthMiddleware).forRoutes({ path: '/connection/properties/:connectionId', method: RequestMethod.PUT }); - consumer.apply(AuthMiddleware).forRoutes({ path: '/connection/properties/:connectionId', method: RequestMethod.DELETE }); - } + public configure(consumer: MiddlewareConsumer): void { + consumer + .apply(AuthMiddleware) + .forRoutes({ path: '/connection/properties/:connectionId', method: RequestMethod.GET }); + consumer + .apply(AuthMiddleware) + .forRoutes({ path: '/connection/properties/:connectionId', method: RequestMethod.POST }); + consumer + .apply(AuthMiddleware) + .forRoutes({ path: '/connection/properties/:connectionId', method: RequestMethod.PUT }); + consumer + .apply(AuthMiddleware) + .forRoutes({ path: '/connection/properties/:connectionId', method: RequestMethod.DELETE }); + } } diff --git a/backend/src/entities/connection-properties/dto/create-connection-properties.dto.ts b/backend/src/entities/connection-properties/dto/create-connection-properties.dto.ts index d8de0121e..149c0502c 100644 --- a/backend/src/entities/connection-properties/dto/create-connection-properties.dto.ts +++ b/backend/src/entities/connection-properties/dto/create-connection-properties.dto.ts @@ -3,60 +3,60 @@ import { IsArray, IsBoolean, IsOptional, IsString, MaxLength, ValidateNested } f import { CreateTableCategoryDto } from '../../table-categories/dto/create-table-category.dto.js'; export class CreateConnectionPropertiesDto { - @IsOptional() - @IsArray() - @ApiProperty({ isArray: true, type: String, required: false }) - hidden_tables: Array; - - @IsOptional() - @IsString() - @ApiProperty({ required: false }) - logo_url: string; - - @IsOptional() - @IsString() - @ApiProperty({ required: false }) - primary_color: string; - - @IsOptional() - @IsString() - @ApiProperty({ required: false }) - secondary_color: string; - - @IsOptional() - @IsString() - @ApiProperty({ required: false }) - hostname: string; - - @IsOptional() - @IsString() - @ApiProperty({ required: false }) - company_name: string; - - @IsOptional() - @IsBoolean() - @ApiProperty({ required: false }) - tables_audit: boolean; - - @IsOptional() - @IsBoolean() - @ApiProperty({ required: false }) - human_readable_table_names: boolean; - - @IsOptional() - @IsBoolean() - @ApiProperty({ required: false }) - allow_ai_requests: boolean; - - @IsOptional() - @IsString() - @MaxLength(255) - @ApiProperty({ required: false }) - default_showing_table: string; - - @IsOptional() - @IsArray() - @ValidateNested({ each: true }) - @ApiProperty({ isArray: true, type: CreateTableCategoryDto, required: false }) - table_categories: Array; + @IsOptional() + @IsArray() + @ApiProperty({ isArray: true, type: String, required: false }) + hidden_tables: Array; + + @IsOptional() + @IsString() + @ApiProperty({ required: false }) + logo_url: string; + + @IsOptional() + @IsString() + @ApiProperty({ required: false }) + primary_color: string; + + @IsOptional() + @IsString() + @ApiProperty({ required: false }) + secondary_color: string; + + @IsOptional() + @IsString() + @ApiProperty({ required: false }) + hostname: string; + + @IsOptional() + @IsString() + @ApiProperty({ required: false }) + company_name: string; + + @IsOptional() + @IsBoolean() + @ApiProperty({ required: false }) + tables_audit: boolean; + + @IsOptional() + @IsBoolean() + @ApiProperty({ required: false }) + human_readable_table_names: boolean; + + @IsOptional() + @IsBoolean() + @ApiProperty({ required: false }) + allow_ai_requests: boolean; + + @IsOptional() + @IsString() + @MaxLength(255) + @ApiProperty({ required: false }) + default_showing_table: string; + + @IsOptional() + @IsArray() + @ValidateNested({ each: true }) + @ApiProperty({ isArray: true, type: CreateTableCategoryDto, required: false }) + table_categories: Array; } diff --git a/backend/src/entities/connection-properties/repository/connection-properties.repository.interface.ts b/backend/src/entities/connection-properties/repository/connection-properties.repository.interface.ts index d99001c38..14a9409dc 100644 --- a/backend/src/entities/connection-properties/repository/connection-properties.repository.interface.ts +++ b/backend/src/entities/connection-properties/repository/connection-properties.repository.interface.ts @@ -1,11 +1,11 @@ import { ConnectionPropertiesEntity } from '../connection-properties.entity.js'; export interface IConnectionPropertiesRepository { - findConnectionProperties(connectionId: string): Promise; + findConnectionProperties(connectionId: string): Promise; - findConnectionPropertiesWithTablesCategories(connectionId: string): Promise; + findConnectionPropertiesWithTablesCategories(connectionId: string): Promise; - saveNewConnectionProperties(connectionProperties: ConnectionPropertiesEntity): Promise; + saveNewConnectionProperties(connectionProperties: ConnectionPropertiesEntity): Promise; - removeConnectionProperties(connectionProperties: ConnectionPropertiesEntity): Promise; + removeConnectionProperties(connectionProperties: ConnectionPropertiesEntity): Promise; } diff --git a/backend/src/entities/connection-properties/repository/custom-connection-properties-repository-extension.ts b/backend/src/entities/connection-properties/repository/custom-connection-properties-repository-extension.ts index 8d01b8aaa..41477ea0c 100644 --- a/backend/src/entities/connection-properties/repository/custom-connection-properties-repository-extension.ts +++ b/backend/src/entities/connection-properties/repository/custom-connection-properties-repository-extension.ts @@ -1,32 +1,32 @@ import { ConnectionPropertiesEntity } from '../connection-properties.entity.js'; export const customConnectionPropertiesRepositoryExtension = { - async findConnectionProperties(connectionId: string): Promise { - const qb = this.createQueryBuilder('connectionProperties').leftJoinAndSelect( - 'connectionProperties.connection', - 'connection', - ); - qb.where('connectionProperties.connection.id = :connection_id', { connection_id: connectionId }); - return await qb.getOne(); - }, + async findConnectionProperties(connectionId: string): Promise { + const qb = this.createQueryBuilder('connectionProperties').leftJoinAndSelect( + 'connectionProperties.connection', + 'connection', + ); + qb.where('connectionProperties.connection.id = :connection_id', { connection_id: connectionId }); + return await qb.getOne(); + }, - async findConnectionPropertiesWithTablesCategories(connectionId: string): Promise { - const qb = this.createQueryBuilder('connectionProperties') - .leftJoin('connectionProperties.connection', 'connection') - .leftJoinAndSelect('connectionProperties.table_categories', 'table_categories'); - qb.where('connectionProperties.connection.id = :connection_id', { connection_id: connectionId }); - return await qb.getOne(); - }, + async findConnectionPropertiesWithTablesCategories(connectionId: string): Promise { + const qb = this.createQueryBuilder('connectionProperties') + .leftJoin('connectionProperties.connection', 'connection') + .leftJoinAndSelect('connectionProperties.table_categories', 'table_categories'); + qb.where('connectionProperties.connection.id = :connection_id', { connection_id: connectionId }); + return await qb.getOne(); + }, - async saveNewConnectionProperties( - connectionProperties: ConnectionPropertiesEntity, - ): Promise { - return this.save(connectionProperties); - }, + async saveNewConnectionProperties( + connectionProperties: ConnectionPropertiesEntity, + ): Promise { + return this.save(connectionProperties); + }, - async removeConnectionProperties( - connectionProperties: ConnectionPropertiesEntity, - ): Promise { - return await this.remove(connectionProperties); - }, + async removeConnectionProperties( + connectionProperties: ConnectionPropertiesEntity, + ): Promise { + return await this.remove(connectionProperties); + }, }; diff --git a/backend/src/entities/connection-properties/use-cases/connection-properties-use.cases.interface.ts b/backend/src/entities/connection-properties/use-cases/connection-properties-use.cases.interface.ts index 67d31d8ae..fc794758f 100644 --- a/backend/src/entities/connection-properties/use-cases/connection-properties-use.cases.interface.ts +++ b/backend/src/entities/connection-properties/use-cases/connection-properties-use.cases.interface.ts @@ -3,23 +3,23 @@ import { CreateConnectionPropertiesDs } from '../application/data-structures/cre import { FoundConnectionPropertiesDs } from '../application/data-structures/found-connection-properties.ds.js'; export interface IFindConnectionProperties { - execute(connectionId: string, inTransaction: InTransactionEnum): Promise; + execute(connectionId: string, inTransaction: InTransactionEnum): Promise; } export interface ICreateConnectionProperties { - execute( - inputData: CreateConnectionPropertiesDs, - inTransaction: InTransactionEnum, - ): Promise; + execute( + inputData: CreateConnectionPropertiesDs, + inTransaction: InTransactionEnum, + ): Promise; } export interface IUpdateConnectionProperties { - execute( - inputData: CreateConnectionPropertiesDs, - inTransaction: InTransactionEnum, - ): Promise; + execute( + inputData: CreateConnectionPropertiesDs, + inTransaction: InTransactionEnum, + ): Promise; } export interface IDeleteConnectionProperties { - execute(connectionId: string, inTransaction: InTransactionEnum): Promise; + execute(connectionId: string, inTransaction: InTransactionEnum): Promise; } diff --git a/backend/src/entities/connection-properties/use-cases/create-connection-properties.use.case.ts b/backend/src/entities/connection-properties/use-cases/create-connection-properties.use.case.ts index e4f4c5078..2069037b9 100644 --- a/backend/src/entities/connection-properties/use-cases/create-connection-properties.use.case.ts +++ b/backend/src/entities/connection-properties/use-cases/create-connection-properties.use.case.ts @@ -12,46 +12,46 @@ import { ICreateConnectionProperties } from './connection-properties-use.cases.i @Injectable() export class CreateConnectionPropertiesUseCase - extends AbstractUseCase - implements ICreateConnectionProperties + extends AbstractUseCase + implements ICreateConnectionProperties { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: CreateConnectionPropertiesDs): Promise { - const { connectionId, master_password, table_categories } = inputData; - let foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( - connectionId, - master_password, - ); - await validateCreateConnectionPropertiesDs(inputData, foundConnection); - const newConnectionProperties = buildConnectionPropertiesEntity(inputData, foundConnection); - const createdConnectionProperties = - await this._dbContext.connectionPropertiesRepository.saveNewConnectionProperties(newConnectionProperties); + protected async implementation(inputData: CreateConnectionPropertiesDs): Promise { + const { connectionId, master_password, table_categories } = inputData; + let foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( + connectionId, + master_password, + ); + await validateCreateConnectionPropertiesDs(inputData, foundConnection); + const newConnectionProperties = buildConnectionPropertiesEntity(inputData, foundConnection); + const createdConnectionProperties = + await this._dbContext.connectionPropertiesRepository.saveNewConnectionProperties(newConnectionProperties); - if (table_categories && table_categories.length > 0) { - const createdCategories = table_categories.map((category) => { - const newCategory = this._dbContext.tableCategoriesRepository.create({ - category_name: category.category_name, - tables: category.tables, - category_color: category.category_color, - category_id: category.category_id, - }); - newCategory.connection_properties = createdConnectionProperties; - return newCategory; - }); - const savedCategories = await this._dbContext.tableCategoriesRepository.save(createdCategories); - createdConnectionProperties.table_categories = savedCategories; - } + if (table_categories && table_categories.length > 0) { + const createdCategories = table_categories.map((category) => { + const newCategory = this._dbContext.tableCategoriesRepository.create({ + category_name: category.category_name, + tables: category.tables, + category_color: category.category_color, + category_id: category.category_id, + }); + newCategory.connection_properties = createdConnectionProperties; + return newCategory; + }); + const savedCategories = await this._dbContext.tableCategoriesRepository.save(createdCategories); + createdConnectionProperties.table_categories = savedCategories; + } - if (foundConnection.masterEncryption && master_password) { - foundConnection = Encryptor.encryptConnectionCredentials(foundConnection, master_password); - } - await this._dbContext.connectionRepository.saveNewConnection(foundConnection); - return buildFoundConnectionPropertiesDs(createdConnectionProperties); - } + if (foundConnection.masterEncryption && master_password) { + foundConnection = Encryptor.encryptConnectionCredentials(foundConnection, master_password); + } + await this._dbContext.connectionRepository.saveNewConnection(foundConnection); + return buildFoundConnectionPropertiesDs(createdConnectionProperties); + } } diff --git a/backend/src/entities/connection-properties/use-cases/delete-connection-properties.use.case.ts b/backend/src/entities/connection-properties/use-cases/delete-connection-properties.use.case.ts index 8d5893bd1..aec211894 100644 --- a/backend/src/entities/connection-properties/use-cases/delete-connection-properties.use.case.ts +++ b/backend/src/entities/connection-properties/use-cases/delete-connection-properties.use.case.ts @@ -10,31 +10,29 @@ import { IDeleteConnectionProperties } from './connection-properties-use.cases.i @Injectable() export class DeleteConnectionPropertiesUseCase - extends AbstractUseCase - implements IDeleteConnectionProperties + extends AbstractUseCase + implements IDeleteConnectionProperties { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(connectionId: string): Promise { - const connectionPropertiesToDelete = await this._dbContext.connectionPropertiesRepository.findConnectionProperties( - connectionId, - ); - if (!connectionPropertiesToDelete) { - throw new HttpException( - { - message: Messages.CONNECTION_PROPERTIES_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - const deletedProperties = await this._dbContext.connectionPropertiesRepository.removeConnectionProperties( - connectionPropertiesToDelete, - ); - return buildFoundConnectionPropertiesDs(deletedProperties); - } + protected async implementation(connectionId: string): Promise { + const connectionPropertiesToDelete = + await this._dbContext.connectionPropertiesRepository.findConnectionProperties(connectionId); + if (!connectionPropertiesToDelete) { + throw new HttpException( + { + message: Messages.CONNECTION_PROPERTIES_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + const deletedProperties = + await this._dbContext.connectionPropertiesRepository.removeConnectionProperties(connectionPropertiesToDelete); + return buildFoundConnectionPropertiesDs(deletedProperties); + } } diff --git a/backend/src/entities/connection-properties/use-cases/find-connection-properties-use.case.ts b/backend/src/entities/connection-properties/use-cases/find-connection-properties-use.case.ts index 36360f45a..f82aea0fd 100644 --- a/backend/src/entities/connection-properties/use-cases/find-connection-properties-use.case.ts +++ b/backend/src/entities/connection-properties/use-cases/find-connection-properties-use.case.ts @@ -8,23 +8,22 @@ import { IFindConnectionProperties } from './connection-properties-use.cases.int @Injectable() export class FindConnectionPropertiesUseCase - extends AbstractUseCase - implements IFindConnectionProperties + extends AbstractUseCase + implements IFindConnectionProperties { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(connectionId: string): Promise { - const foundConnectionProperties = await this._dbContext.connectionPropertiesRepository.findConnectionProperties( - connectionId, - ); - if (!foundConnectionProperties) { - return null; - } - return buildFoundConnectionPropertiesDs(foundConnectionProperties); - } + protected async implementation(connectionId: string): Promise { + const foundConnectionProperties = + await this._dbContext.connectionPropertiesRepository.findConnectionProperties(connectionId); + if (!foundConnectionProperties) { + return null; + } + return buildFoundConnectionPropertiesDs(foundConnectionProperties); + } } diff --git a/backend/src/entities/connection-properties/use-cases/update-connection-properties.use.case.ts b/backend/src/entities/connection-properties/use-cases/update-connection-properties.use.case.ts index d96c8c121..15236e880 100644 --- a/backend/src/entities/connection-properties/use-cases/update-connection-properties.use.case.ts +++ b/backend/src/entities/connection-properties/use-cases/update-connection-properties.use.case.ts @@ -4,105 +4,105 @@ import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { TableCategoriesEntity } from '../../table-categories/table-categories.entity.js'; import { CreateConnectionPropertiesDs } from '../application/data-structures/create-connection-properties.ds.js'; import { FoundConnectionPropertiesDs } from '../application/data-structures/found-connection-properties.ds.js'; import { buildFoundConnectionPropertiesDs } from '../utils/build-found-connection-properties-ds.js'; import { - buildUpdateConnectionPropertiesObject, - IUpdateConnectionPropertiesObject, + buildUpdateConnectionPropertiesObject, + IUpdateConnectionPropertiesObject, } from '../utils/build-update-connection-properties-object.js'; import { validateCreateConnectionPropertiesDs } from '../utils/validate-create-connection-properties-ds.js'; import { IUpdateConnectionProperties } from './connection-properties-use.cases.interface.js'; -import { TableCategoriesEntity } from '../../table-categories/table-categories.entity.js'; @Injectable() export class UpdateConnectionPropertiesUseCase - extends AbstractUseCase - implements IUpdateConnectionProperties + extends AbstractUseCase + implements IUpdateConnectionProperties { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: CreateConnectionPropertiesDs): Promise { - const { connectionId, master_password, table_categories } = inputData; - const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( - connectionId, - master_password, - ); - await validateCreateConnectionPropertiesDs(inputData, foundConnection); - const connectionPropertiesToUpdate = - await this._dbContext.connectionPropertiesRepository.findConnectionProperties(connectionId); - if (!connectionPropertiesToUpdate) { - throw new HttpException( - { - message: Messages.CONNECTION_PROPERTIES_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - const updatePropertiesObject: IUpdateConnectionPropertiesObject = buildUpdateConnectionPropertiesObject(inputData); - const updated = Object.assign(connectionPropertiesToUpdate, updatePropertiesObject); + protected async implementation(inputData: CreateConnectionPropertiesDs): Promise { + const { connectionId, master_password, table_categories } = inputData; + const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( + connectionId, + master_password, + ); + await validateCreateConnectionPropertiesDs(inputData, foundConnection); + const connectionPropertiesToUpdate = + await this._dbContext.connectionPropertiesRepository.findConnectionProperties(connectionId); + if (!connectionPropertiesToUpdate) { + throw new HttpException( + { + message: Messages.CONNECTION_PROPERTIES_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + const updatePropertiesObject: IUpdateConnectionPropertiesObject = buildUpdateConnectionPropertiesObject(inputData); + const updated = Object.assign(connectionPropertiesToUpdate, updatePropertiesObject); - const foundCategories = await this._dbContext.tableCategoriesRepository.find({ - where: { connection_properties_id: connectionPropertiesToUpdate.id }, - }); + const foundCategories = await this._dbContext.tableCategoriesRepository.find({ + where: { connection_properties_id: connectionPropertiesToUpdate.id }, + }); - const newCategories: Array = []; + const newCategories: Array = []; - if (table_categories && table_categories.length > 0) { - const categoriesToRemove = foundCategories.filter((foundCategory) => { - return !table_categories?.some((inputCategory) => inputCategory.category_id === foundCategory.category_id); - }); - if (categoriesToRemove && categoriesToRemove.length > 0) { - await this._dbContext.tableCategoriesRepository.remove(categoriesToRemove); - } + if (table_categories && table_categories.length > 0) { + const categoriesToRemove = foundCategories.filter((foundCategory) => { + return !table_categories?.some((inputCategory) => inputCategory.category_id === foundCategory.category_id); + }); + if (categoriesToRemove && categoriesToRemove.length > 0) { + await this._dbContext.tableCategoriesRepository.remove(categoriesToRemove); + } - const categoriesToCreate = table_categories.filter((inputCategory) => { - return !foundCategories.some((foundCategory) => foundCategory.category_id === inputCategory.category_id); - }); + const categoriesToCreate = table_categories.filter((inputCategory) => { + return !foundCategories.some((foundCategory) => foundCategory.category_id === inputCategory.category_id); + }); - if (categoriesToCreate && categoriesToCreate.length > 0) { - const createdCategories = categoriesToCreate.map((category) => { - const newCategory = this._dbContext.tableCategoriesRepository.create({ - category_name: category.category_name, - tables: category.tables, - category_color: category.category_color, - category_id: category.category_id, - }); - newCategory.connection_properties = connectionPropertiesToUpdate; - return newCategory; - }); - const savedNewCategories = await this._dbContext.tableCategoriesRepository.save(createdCategories); - newCategories.push(...savedNewCategories); - } + if (categoriesToCreate && categoriesToCreate.length > 0) { + const createdCategories = categoriesToCreate.map((category) => { + const newCategory = this._dbContext.tableCategoriesRepository.create({ + category_name: category.category_name, + tables: category.tables, + category_color: category.category_color, + category_id: category.category_id, + }); + newCategory.connection_properties = connectionPropertiesToUpdate; + return newCategory; + }); + const savedNewCategories = await this._dbContext.tableCategoriesRepository.save(createdCategories); + newCategories.push(...savedNewCategories); + } - const categoriesToUpdate = table_categories.filter((inputCategory) => { - return foundCategories.some((foundCategory) => foundCategory.category_id === inputCategory.category_id); - }); + const categoriesToUpdate = table_categories.filter((inputCategory) => { + return foundCategories.some((foundCategory) => foundCategory.category_id === inputCategory.category_id); + }); - for (const category of categoriesToUpdate) { - const categoryToUpdate = foundCategories.find( - (foundCategory) => foundCategory.category_id === category.category_id, - ); - if (categoryToUpdate) { - categoryToUpdate.category_name = category.category_name; - categoryToUpdate.category_color = category.category_color; - categoryToUpdate.tables = category.tables; - const savedUpdatedCategory = await this._dbContext.tableCategoriesRepository.save(categoryToUpdate); - newCategories.push(savedUpdatedCategory); - } - } - } else { - newCategories.push(...foundCategories); - } + for (const category of categoriesToUpdate) { + const categoryToUpdate = foundCategories.find( + (foundCategory) => foundCategory.category_id === category.category_id, + ); + if (categoryToUpdate) { + categoryToUpdate.category_name = category.category_name; + categoryToUpdate.category_color = category.category_color; + categoryToUpdate.tables = category.tables; + const savedUpdatedCategory = await this._dbContext.tableCategoriesRepository.save(categoryToUpdate); + newCategories.push(savedUpdatedCategory); + } + } + } else { + newCategories.push(...foundCategories); + } - const updatedProperties = await this._dbContext.connectionPropertiesRepository.saveNewConnectionProperties(updated); - updatedProperties.table_categories = newCategories; + const updatedProperties = await this._dbContext.connectionPropertiesRepository.saveNewConnectionProperties(updated); + updatedProperties.table_categories = newCategories; - return buildFoundConnectionPropertiesDs(updatedProperties); - } + return buildFoundConnectionPropertiesDs(updatedProperties); + } } diff --git a/backend/src/entities/connection-properties/utils/build-connection-properties-entity.ts b/backend/src/entities/connection-properties/utils/build-connection-properties-entity.ts index 2e0b4ed93..4e487721a 100644 --- a/backend/src/entities/connection-properties/utils/build-connection-properties-entity.ts +++ b/backend/src/entities/connection-properties/utils/build-connection-properties-entity.ts @@ -1,23 +1,23 @@ -import { ConnectionPropertiesEntity } from '../connection-properties.entity.js'; -import { CreateConnectionPropertiesDs } from '../application/data-structures/create-connection-properties.ds.js'; import { ConnectionEntity } from '../../connection/connection.entity.js'; +import { CreateConnectionPropertiesDs } from '../application/data-structures/create-connection-properties.ds.js'; +import { ConnectionPropertiesEntity } from '../connection-properties.entity.js'; export function buildConnectionPropertiesEntity( - propertiesInfo: CreateConnectionPropertiesDs, - connection: ConnectionEntity, + propertiesInfo: CreateConnectionPropertiesDs, + connection: ConnectionEntity, ): ConnectionPropertiesEntity { - const { hidden_tables } = propertiesInfo; - const newConnectionProperties = new ConnectionPropertiesEntity(); - newConnectionProperties.connection = connection; - newConnectionProperties.hidden_tables = hidden_tables; - newConnectionProperties.logo_url = propertiesInfo.logo_url; - newConnectionProperties.primary_color = propertiesInfo.primary_color; - newConnectionProperties.secondary_color = propertiesInfo.secondary_color; - newConnectionProperties.hostname = propertiesInfo.hostname; - newConnectionProperties.company_name = propertiesInfo.company_name; - newConnectionProperties.tables_audit = propertiesInfo.tables_audit; - newConnectionProperties.human_readable_table_names = propertiesInfo.human_readable_table_names; - newConnectionProperties.allow_ai_requests = propertiesInfo.allow_ai_requests; - newConnectionProperties.default_showing_table = propertiesInfo.default_showing_table; - return newConnectionProperties; + const { hidden_tables } = propertiesInfo; + const newConnectionProperties = new ConnectionPropertiesEntity(); + newConnectionProperties.connection = connection; + newConnectionProperties.hidden_tables = hidden_tables; + newConnectionProperties.logo_url = propertiesInfo.logo_url; + newConnectionProperties.primary_color = propertiesInfo.primary_color; + newConnectionProperties.secondary_color = propertiesInfo.secondary_color; + newConnectionProperties.hostname = propertiesInfo.hostname; + newConnectionProperties.company_name = propertiesInfo.company_name; + newConnectionProperties.tables_audit = propertiesInfo.tables_audit; + newConnectionProperties.human_readable_table_names = propertiesInfo.human_readable_table_names; + newConnectionProperties.allow_ai_requests = propertiesInfo.allow_ai_requests; + newConnectionProperties.default_showing_table = propertiesInfo.default_showing_table; + return newConnectionProperties; } diff --git a/backend/src/entities/connection-properties/utils/build-found-connection-properties-ds.ts b/backend/src/entities/connection-properties/utils/build-found-connection-properties-ds.ts index 9e4e8568d..f038830a3 100644 --- a/backend/src/entities/connection-properties/utils/build-found-connection-properties-ds.ts +++ b/backend/src/entities/connection-properties/utils/build-found-connection-properties-ds.ts @@ -1,31 +1,31 @@ -import { ConnectionPropertiesEntity } from '../connection-properties.entity.js'; import { FoundConnectionPropertiesDs } from '../application/data-structures/found-connection-properties.ds.js'; +import { ConnectionPropertiesEntity } from '../connection-properties.entity.js'; export function buildFoundConnectionPropertiesDs( - connectionProperties: ConnectionPropertiesEntity, + connectionProperties: ConnectionPropertiesEntity, ): FoundConnectionPropertiesDs { - return { - id: connectionProperties.id, - hidden_tables: connectionProperties.hidden_tables, - connectionId: connectionProperties.connection?.id, - logo_url: connectionProperties.logo_url, - primary_color: connectionProperties.primary_color, - secondary_color: connectionProperties.secondary_color, - hostname: connectionProperties.hostname, - company_name: connectionProperties.company_name, - tables_audit: connectionProperties.tables_audit, - human_readable_table_names: connectionProperties.human_readable_table_names, - allow_ai_requests: connectionProperties.allow_ai_requests, - default_showing_table: connectionProperties.default_showing_table, - table_categories: connectionProperties.table_categories - ? connectionProperties.table_categories.map((c) => { - return { - category_id: c.category_id, - category_name: c.category_name, - tables: c.tables, - category_color: c.category_color, - }; - }) - : [], - }; + return { + id: connectionProperties.id, + hidden_tables: connectionProperties.hidden_tables, + connectionId: connectionProperties.connection?.id, + logo_url: connectionProperties.logo_url, + primary_color: connectionProperties.primary_color, + secondary_color: connectionProperties.secondary_color, + hostname: connectionProperties.hostname, + company_name: connectionProperties.company_name, + tables_audit: connectionProperties.tables_audit, + human_readable_table_names: connectionProperties.human_readable_table_names, + allow_ai_requests: connectionProperties.allow_ai_requests, + default_showing_table: connectionProperties.default_showing_table, + table_categories: connectionProperties.table_categories + ? connectionProperties.table_categories.map((c) => { + return { + category_id: c.category_id, + category_name: c.category_name, + tables: c.tables, + category_color: c.category_color, + }; + }) + : [], + }; } diff --git a/backend/src/entities/connection-properties/utils/build-update-connection-properties-object.ts b/backend/src/entities/connection-properties/utils/build-update-connection-properties-object.ts index 071de698e..bec05ea59 100644 --- a/backend/src/entities/connection-properties/utils/build-update-connection-properties-object.ts +++ b/backend/src/entities/connection-properties/utils/build-update-connection-properties-object.ts @@ -1,43 +1,43 @@ import { CreateConnectionPropertiesDs } from '../application/data-structures/create-connection-properties.ds.js'; export function buildUpdateConnectionPropertiesObject( - inputData: CreateConnectionPropertiesDs, + inputData: CreateConnectionPropertiesDs, ): IUpdateConnectionPropertiesObject { - const { - hidden_tables, - logo_url, - primary_color, - secondary_color, - hostname, - company_name, - tables_audit, - human_readable_table_names, - allow_ai_requests, - default_showing_table, - } = inputData; - return { - hidden_tables: hidden_tables, - logo_url: logo_url, - primary_color: primary_color, - secondary_color: secondary_color, - hostname: hostname, - company_name: company_name, - tables_audit: tables_audit, - human_readable_table_names: human_readable_table_names, - allow_ai_requests: allow_ai_requests, - default_showing_table: default_showing_table, - }; + const { + hidden_tables, + logo_url, + primary_color, + secondary_color, + hostname, + company_name, + tables_audit, + human_readable_table_names, + allow_ai_requests, + default_showing_table, + } = inputData; + return { + hidden_tables: hidden_tables, + logo_url: logo_url, + primary_color: primary_color, + secondary_color: secondary_color, + hostname: hostname, + company_name: company_name, + tables_audit: tables_audit, + human_readable_table_names: human_readable_table_names, + allow_ai_requests: allow_ai_requests, + default_showing_table: default_showing_table, + }; } export interface IUpdateConnectionPropertiesObject { - hidden_tables: Array; - logo_url: string; - primary_color: string; - secondary_color: string; - hostname: string; - company_name: string; - tables_audit: boolean; - human_readable_table_names: boolean; - allow_ai_requests: boolean; - default_showing_table: string; + hidden_tables: Array; + logo_url: string; + primary_color: string; + secondary_color: string; + hostname: string; + company_name: string; + tables_audit: boolean; + human_readable_table_names: boolean; + allow_ai_requests: boolean; + default_showing_table: string; } diff --git a/backend/src/entities/connection-properties/utils/validate-create-connection-properties-ds.ts b/backend/src/entities/connection-properties/utils/validate-create-connection-properties-ds.ts index af6e95fad..42c331f78 100644 --- a/backend/src/entities/connection-properties/utils/validate-create-connection-properties-ds.ts +++ b/backend/src/entities/connection-properties/utils/validate-create-connection-properties-ds.ts @@ -1,60 +1,60 @@ -import { CreateConnectionPropertiesDs } from '../application/data-structures/create-connection-properties.ds.js'; -import { toPrettyErrorsMsg } from '../../../helpers/index.js'; +import { HttpStatus } from '@nestjs/common'; import { HttpException } from '@nestjs/common/exceptions/http.exception.js'; +import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import { Messages } from '../../../exceptions/text/messages.js'; -import { HttpStatus } from '@nestjs/common'; +import { toPrettyErrorsMsg } from '../../../helpers/index.js'; import { ConnectionEntity } from '../../connection/connection.entity.js'; -import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import { validateTableCategories } from '../../table-categories/utils/validate-table-categories.util.js'; +import { CreateConnectionPropertiesDs } from '../application/data-structures/create-connection-properties.ds.js'; export async function validateCreateConnectionPropertiesDs( - createConnectionProperties: CreateConnectionPropertiesDs, - connection: ConnectionEntity, + createConnectionProperties: CreateConnectionPropertiesDs, + connection: ConnectionEntity, ): Promise { - const { hidden_tables, default_showing_table, table_categories } = createConnectionProperties; - const errors = []; - const dao = getDataAccessObject(connection); - const tablesInConnection = (await dao.getTablesFromDB()).map((table) => table.tableName); - if (hidden_tables && !Array.isArray(hidden_tables)) { - errors.push(Messages.HIDDEN_TABLES_MUST_BE_ARRAY); - } - if (hidden_tables && hidden_tables.length > 0) { - for (const hiddenTable of hidden_tables) { - if (!tablesInConnection.includes(hiddenTable)) { - errors.push(Messages.TABLE_WITH_NAME_NOT_EXISTS(hiddenTable)); - } - } - if (hidden_tables.includes(default_showing_table)) { - errors.push(Messages.CANT_SHOW_TABLE_AND_EXCLUDE(default_showing_table)); - } - } + const { hidden_tables, default_showing_table, table_categories } = createConnectionProperties; + const errors = []; + const dao = getDataAccessObject(connection); + const tablesInConnection = (await dao.getTablesFromDB()).map((table) => table.tableName); + if (hidden_tables && !Array.isArray(hidden_tables)) { + errors.push(Messages.HIDDEN_TABLES_MUST_BE_ARRAY); + } + if (hidden_tables && hidden_tables.length > 0) { + for (const hiddenTable of hidden_tables) { + if (!tablesInConnection.includes(hiddenTable)) { + errors.push(Messages.TABLE_WITH_NAME_NOT_EXISTS(hiddenTable)); + } + } + if (hidden_tables.includes(default_showing_table)) { + errors.push(Messages.CANT_SHOW_TABLE_AND_EXCLUDE(default_showing_table)); + } + } - if (default_showing_table && !tablesInConnection.includes(default_showing_table)) { - errors.push(Messages.TABLE_WITH_NAME_NOT_EXISTS(default_showing_table)); - } + if (default_showing_table && !tablesInConnection.includes(default_showing_table)) { + errors.push(Messages.TABLE_WITH_NAME_NOT_EXISTS(default_showing_table)); + } - if (table_categories && table_categories.length > 0) { - const tablesInCategories = table_categories.flatMap((category) => category.tables); - const uniqueTablesInCategories = Array.from(new Set(tablesInCategories)); - for (const table of uniqueTablesInCategories) { - if (!tablesInConnection.includes(table)) { - errors.push(Messages.TABLE_WITH_NAME_NOT_EXISTS(table)); - } - if (hidden_tables?.includes(table)) { - errors.push(Messages.CANT_CATEGORIZE_HIDDEN_TABLE(table)); - } - } + if (table_categories && table_categories.length > 0) { + const tablesInCategories = table_categories.flatMap((category) => category.tables); + const uniqueTablesInCategories = Array.from(new Set(tablesInCategories)); + for (const table of uniqueTablesInCategories) { + if (!tablesInConnection.includes(table)) { + errors.push(Messages.TABLE_WITH_NAME_NOT_EXISTS(table)); + } + if (hidden_tables?.includes(table)) { + errors.push(Messages.CANT_CATEGORIZE_HIDDEN_TABLE(table)); + } + } - await validateTableCategories(table_categories, connection); - } + await validateTableCategories(table_categories, connection); + } - if (errors.length > 0) { - throw new HttpException( - { - message: Messages.CONNECTION_PROPERTIES_INVALID + ' : ' + toPrettyErrorsMsg(errors), - }, - HttpStatus.BAD_REQUEST, - ); - } - return true; + if (errors.length > 0) { + throw new HttpException( + { + message: Messages.CONNECTION_PROPERTIES_INVALID + ' : ' + toPrettyErrorsMsg(errors), + }, + HttpStatus.BAD_REQUEST, + ); + } + return true; } diff --git a/backend/src/entities/connection/application/data-structures/create-connection.ds.ts b/backend/src/entities/connection/application/data-structures/create-connection.ds.ts index ecbf39224..dbfb12ede 100644 --- a/backend/src/entities/connection/application/data-structures/create-connection.ds.ts +++ b/backend/src/entities/connection/application/data-structures/create-connection.ds.ts @@ -1,30 +1,30 @@ import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; export class CreateConnectionDs { - connection_parameters: { - title: string; - masterEncryption: boolean; - type: ConnectionTypesEnum; - host: string; - port: number; - username: string; - password: string; - database: string; - schema: string; - sid: string; - ssh: boolean; - privateSSHKey: string; - sshHost: string; - sshPort: number; - sshUsername: string; - ssl: boolean; - cert: string; - azure_encryption: boolean; - authSource: string; - dataCenter: string; - }; - creation_info: { - authorId: string; - masterPwd: string; - }; + connection_parameters: { + title: string; + masterEncryption: boolean; + type: ConnectionTypesEnum; + host: string; + port: number; + username: string; + password: string; + database: string; + schema: string; + sid: string; + ssh: boolean; + privateSSHKey: string; + sshHost: string; + sshPort: number; + sshUsername: string; + ssl: boolean; + cert: string; + azure_encryption: boolean; + authSource: string; + dataCenter: string; + }; + creation_info: { + authorId: string; + masterPwd: string; + }; } diff --git a/backend/src/entities/connection/application/data-structures/create-group-in-connection.ds.ts b/backend/src/entities/connection/application/data-structures/create-group-in-connection.ds.ts index a1f0b5df5..7dea8f36b 100644 --- a/backend/src/entities/connection/application/data-structures/create-group-in-connection.ds.ts +++ b/backend/src/entities/connection/application/data-structures/create-group-in-connection.ds.ts @@ -1,9 +1,9 @@ export class CreateGroupInConnectionDs { - group_parameters: { - title: string; - connectionId: string; - }; - creation_info: { - cognitoUserName: string; - }; + group_parameters: { + title: string; + connectionId: string; + }; + creation_info: { + cognitoUserName: string; + }; } diff --git a/backend/src/entities/connection/application/data-structures/delete-connection.ds.ts b/backend/src/entities/connection/application/data-structures/delete-connection.ds.ts index 239978f97..bf2873ce1 100644 --- a/backend/src/entities/connection/application/data-structures/delete-connection.ds.ts +++ b/backend/src/entities/connection/application/data-structures/delete-connection.ds.ts @@ -1,5 +1,5 @@ export class DeleteConnectionDs { - connectionId: string; - cognitoUserName: string; - masterPwd: string; + connectionId: string; + cognitoUserName: string; + masterPwd: string; } diff --git a/backend/src/entities/connection/application/data-structures/delete-group-in-connection.ds.ts b/backend/src/entities/connection/application/data-structures/delete-group-in-connection.ds.ts index 80304d64a..a7fa18a14 100644 --- a/backend/src/entities/connection/application/data-structures/delete-group-in-connection.ds.ts +++ b/backend/src/entities/connection/application/data-structures/delete-group-in-connection.ds.ts @@ -1,5 +1,5 @@ export class DeleteGroupInConnectionDs { - groupId: string; - connectionId: string; - cognitoUserName: string; + groupId: string; + connectionId: string; + cognitoUserName: string; } diff --git a/backend/src/entities/connection/application/data-structures/find-one-connection.ds.ts b/backend/src/entities/connection/application/data-structures/find-one-connection.ds.ts index 79609e96b..8a924a2fc 100644 --- a/backend/src/entities/connection/application/data-structures/find-one-connection.ds.ts +++ b/backend/src/entities/connection/application/data-structures/find-one-connection.ds.ts @@ -1,5 +1,5 @@ export class FindOneConnectionDs { - cognitoUserName: string; - connectionId: string; - masterPwd: string; + cognitoUserName: string; + connectionId: string; + masterPwd: string; } diff --git a/backend/src/entities/connection/application/data-structures/found-connections.ds.ts b/backend/src/entities/connection/application/data-structures/found-connections.ds.ts index da7d28fd4..dcb072d0b 100644 --- a/backend/src/entities/connection/application/data-structures/found-connections.ds.ts +++ b/backend/src/entities/connection/application/data-structures/found-connections.ds.ts @@ -6,166 +6,166 @@ import { SimpleFoundUserInfoDs } from '../../../user/dto/found-user.dto.js'; import { UserEntity } from '../../../user/user.entity.js'; export class FoundDirectConnectionsDs { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty({ required: false }) - title?: string; + @ApiProperty({ required: false }) + title?: string; - @ApiProperty() - masterEncryption: boolean; + @ApiProperty() + masterEncryption: boolean; - @ApiProperty({ enum: ConnectionTypesEnum }) - type?: ConnectionTypesEnum | string; + @ApiProperty({ enum: ConnectionTypesEnum }) + type?: ConnectionTypesEnum | string; - @ApiProperty() - host?: string; + @ApiProperty() + host?: string; - @ApiProperty() - port?: number | null; + @ApiProperty() + port?: number | null; - @ApiProperty() - username?: string; + @ApiProperty() + username?: string; - @ApiProperty() - database?: string; + @ApiProperty() + database?: string; - @ApiProperty() - schema?: string; + @ApiProperty() + schema?: string; - @ApiProperty({ required: false }) - sid?: string; + @ApiProperty({ required: false }) + sid?: string; - @ApiProperty({ required: false }) - createdAt?: Date; + @ApiProperty({ required: false }) + createdAt?: Date; - @ApiProperty({ required: false }) - updatedAt?: Date; + @ApiProperty({ required: false }) + updatedAt?: Date; - @ApiProperty() - ssh?: boolean; + @ApiProperty() + ssh?: boolean; - @ApiProperty({ required: false }) - sshHost?: string; + @ApiProperty({ required: false }) + sshHost?: string; - @ApiProperty({ required: false }) - sshPort?: number; + @ApiProperty({ required: false }) + sshPort?: number; - @ApiProperty() - ssl?: boolean; + @ApiProperty() + ssl?: boolean; - @ApiProperty({ required: false }) - cert?: string; + @ApiProperty({ required: false }) + cert?: string; - @ApiProperty({ required: false }) - author?: UserEntity | string; + @ApiProperty({ required: false }) + author?: UserEntity | string; - @ApiProperty({ required: false }) - token?: string; + @ApiProperty({ required: false }) + token?: string; - @ApiProperty({ required: false }) - azure_encryption?: boolean; + @ApiProperty({ required: false }) + azure_encryption?: boolean; - @ApiProperty() - signing_key: string; + @ApiProperty() + signing_key: string; - @ApiProperty({ required: false }) - authSource?: string; + @ApiProperty({ required: false }) + authSource?: string; - @ApiProperty({ required: false }) - dataCenter?: string; + @ApiProperty({ required: false }) + dataCenter?: string; - @ApiProperty() - isTestConnection: boolean; + @ApiProperty() + isTestConnection: boolean; - @ApiProperty({ required: false }) - connection_properties?: any; + @ApiProperty({ required: false }) + connection_properties?: any; - @ApiProperty() - isFrozen: boolean; + @ApiProperty() + isFrozen: boolean; } export class FoundDirectConnectionsNonePermissionDs { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty({ required: false }) - title?: string; + @ApiProperty({ required: false }) + title?: string; - @ApiProperty() - type?: ConnectionTypesEnum | string; + @ApiProperty() + type?: ConnectionTypesEnum | string; - @ApiProperty() - database: string; + @ApiProperty() + database: string; - @ApiProperty() - isTestConnection: boolean; + @ApiProperty() + isTestConnection: boolean; - @ApiProperty() - connection_properties: any; + @ApiProperty() + connection_properties: any; - @ApiProperty() - isFrozen: boolean; + @ApiProperty() + isFrozen: boolean; } export class FoundAgentConnectionsDs { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - title?: string; + @ApiProperty() + title?: string; - @ApiProperty({ enum: ConnectionTypesEnum }) - type?: ConnectionTypesEnum | string; + @ApiProperty({ enum: ConnectionTypesEnum }) + type?: ConnectionTypesEnum | string; - @ApiProperty({ required: false }) - author: UserEntity | string; + @ApiProperty({ required: false }) + author: UserEntity | string; - @ApiProperty() - token: string; + @ApiProperty() + token: string; - @ApiProperty() - signing_key: string; + @ApiProperty() + signing_key: string; - @ApiProperty() - isTestConnection: boolean; + @ApiProperty() + isTestConnection: boolean; - @ApiProperty({ required: false }) - connection_properties: any; + @ApiProperty({ required: false }) + connection_properties: any; } export class FoundSipleConnectionInfoDS { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - title?: string; + @ApiProperty() + title?: string; - @ApiProperty({ enum: ConnectionTypesEnum }) - type?: ConnectionTypesEnum | string; + @ApiProperty({ enum: ConnectionTypesEnum }) + type?: ConnectionTypesEnum | string; - @ApiProperty() - isTestConnection: boolean; + @ApiProperty() + isTestConnection: boolean; - @ApiProperty({ required: false }) - author: SimpleFoundUserInfoDs; + @ApiProperty({ required: false }) + author: SimpleFoundUserInfoDs; - @ApiProperty({ isArray: true }) - groups: Array; + @ApiProperty({ isArray: true }) + groups: Array; } export class ConnectionWithAccessLevelDS { - @ApiProperty() - connection: FoundDirectConnectionsDs | FoundAgentConnectionsDs | FoundDirectConnectionsNonePermissionDs; + @ApiProperty() + connection: FoundDirectConnectionsDs | FoundAgentConnectionsDs | FoundDirectConnectionsNonePermissionDs; - @ApiProperty() - accessLevel: AccessLevelEnum; + @ApiProperty() + accessLevel: AccessLevelEnum; } export class FoundConnectionsDs { - @ApiProperty({ isArray: true, type: ConnectionWithAccessLevelDS }) - connections: Array; + @ApiProperty({ isArray: true, type: ConnectionWithAccessLevelDS }) + connections: Array; - @ApiProperty() - connectionsCount: number; + @ApiProperty() + connectionsCount: number; } diff --git a/backend/src/entities/connection/application/data-structures/found-one-connection.ds.ts b/backend/src/entities/connection/application/data-structures/found-one-connection.ds.ts index 80457060c..d2886e669 100644 --- a/backend/src/entities/connection/application/data-structures/found-one-connection.ds.ts +++ b/backend/src/entities/connection/application/data-structures/found-one-connection.ds.ts @@ -1,22 +1,22 @@ +import { ApiProperty } from '@nestjs/swagger'; import { AccessLevelEnum } from '../../../../enums/index.js'; import { FoundConnectionPropertiesDs } from '../../../connection-properties/application/data-structures/found-connection-properties.ds.js'; import { - FoundAgentConnectionsDs, - FoundDirectConnectionsDs, - FoundDirectConnectionsNonePermissionDs, + FoundAgentConnectionsDs, + FoundDirectConnectionsDs, + FoundDirectConnectionsNonePermissionDs, } from './found-connections.ds.js'; -import { ApiProperty } from '@nestjs/swagger'; export class FoundOneConnectionDs { - @ApiProperty({ type: FoundDirectConnectionsDs }) - connection: FoundDirectConnectionsDs | FoundAgentConnectionsDs | FoundDirectConnectionsNonePermissionDs; + @ApiProperty({ type: FoundDirectConnectionsDs }) + connection: FoundDirectConnectionsDs | FoundAgentConnectionsDs | FoundDirectConnectionsNonePermissionDs; - @ApiProperty({ enum: AccessLevelEnum }) - accessLevel: AccessLevelEnum; + @ApiProperty({ enum: AccessLevelEnum }) + accessLevel: AccessLevelEnum; - @ApiProperty() - groupManagement: boolean; + @ApiProperty() + groupManagement: boolean; - @ApiProperty({ type: FoundConnectionPropertiesDs }) - connectionProperties: FoundConnectionPropertiesDs; + @ApiProperty({ type: FoundConnectionPropertiesDs }) + connectionProperties: FoundConnectionPropertiesDs; } diff --git a/backend/src/entities/connection/application/data-structures/found-permissions-in-connection.ds.ts b/backend/src/entities/connection/application/data-structures/found-permissions-in-connection.ds.ts index aab3534d0..af4acff48 100644 --- a/backend/src/entities/connection/application/data-structures/found-permissions-in-connection.ds.ts +++ b/backend/src/entities/connection/application/data-structures/found-permissions-in-connection.ds.ts @@ -2,56 +2,56 @@ import { ApiProperty } from '@nestjs/swagger'; import { AccessLevelEnum } from '../../../../enums/index.js'; export class FoundConnectionPermissionsDs { - @ApiProperty() - connectionId: string; + @ApiProperty() + connectionId: string; - @ApiProperty({ enum: AccessLevelEnum }) - accessLevel: AccessLevelEnum; + @ApiProperty({ enum: AccessLevelEnum }) + accessLevel: AccessLevelEnum; } export class FoundConnectionGroupPermissionDs { - @ApiProperty() - groupId: string; + @ApiProperty() + groupId: string; - @ApiProperty({ enum: AccessLevelEnum }) - accessLevel: AccessLevelEnum; + @ApiProperty({ enum: AccessLevelEnum }) + accessLevel: AccessLevelEnum; } export class FoundTablePermissionsDs { - @ApiProperty() - visibility: boolean; + @ApiProperty() + visibility: boolean; - @ApiProperty() - readonly: boolean; + @ApiProperty() + readonly: boolean; - @ApiProperty() - add: boolean; + @ApiProperty() + add: boolean; - @ApiProperty() - delete: boolean; + @ApiProperty() + delete: boolean; - @ApiProperty() - edit: boolean; + @ApiProperty() + edit: boolean; } export class FoundTablesWithPermissionsDs { - @ApiProperty() - tableName: string; + @ApiProperty() + tableName: string; - @ApiProperty() - display_name: string; + @ApiProperty() + display_name: string; - @ApiProperty({ type: FoundTablePermissionsDs }) - accessLevel: FoundTablePermissionsDs; + @ApiProperty({ type: FoundTablePermissionsDs }) + accessLevel: FoundTablePermissionsDs; } export class FoundPermissionsInConnectionDs { - @ApiProperty({ type: FoundConnectionPermissionsDs }) - connection: FoundConnectionPermissionsDs; + @ApiProperty({ type: FoundConnectionPermissionsDs }) + connection: FoundConnectionPermissionsDs; - @ApiProperty({ type: FoundConnectionGroupPermissionDs }) - group: FoundConnectionGroupPermissionDs; + @ApiProperty({ type: FoundConnectionGroupPermissionDs }) + group: FoundConnectionGroupPermissionDs; - @ApiProperty({ isArray: true, type: FoundTablesWithPermissionsDs }) - tables: Array; + @ApiProperty({ isArray: true, type: FoundTablesWithPermissionsDs }) + tables: Array; } diff --git a/backend/src/entities/connection/application/data-structures/get-groups-in-connection.ds.ts b/backend/src/entities/connection/application/data-structures/get-groups-in-connection.ds.ts index 1a394a9e0..e07d980ec 100644 --- a/backend/src/entities/connection/application/data-structures/get-groups-in-connection.ds.ts +++ b/backend/src/entities/connection/application/data-structures/get-groups-in-connection.ds.ts @@ -1,4 +1,4 @@ export class GetGroupsInConnectionDs { - cognitoUserName: string; - connectionId: string; + cognitoUserName: string; + connectionId: string; } diff --git a/backend/src/entities/connection/application/data-structures/get-permissions-in-connection.ds.ts b/backend/src/entities/connection/application/data-structures/get-permissions-in-connection.ds.ts index b2954f825..1d8abbc39 100644 --- a/backend/src/entities/connection/application/data-structures/get-permissions-in-connection.ds.ts +++ b/backend/src/entities/connection/application/data-structures/get-permissions-in-connection.ds.ts @@ -1,6 +1,6 @@ export class GetPermissionsInConnectionDs { - cognitoUserName: string; - connectionId: string; - groupId: string; - masterPwd: string; + cognitoUserName: string; + connectionId: string; + groupId: string; + masterPwd: string; } diff --git a/backend/src/entities/connection/application/data-structures/restored-connection.ds.ts b/backend/src/entities/connection/application/data-structures/restored-connection.ds.ts index 5a6fe4ed6..0e8afc17b 100644 --- a/backend/src/entities/connection/application/data-structures/restored-connection.ds.ts +++ b/backend/src/entities/connection/application/data-structures/restored-connection.ds.ts @@ -2,6 +2,6 @@ import { ApiProperty } from '@nestjs/swagger'; import { CreatedConnectionDTO } from '../dto/created-connection.dto.js'; export class RestoredConnectionDs { - @ApiProperty() - connection: CreatedConnectionDTO; + @ApiProperty() + connection: CreatedConnectionDTO; } diff --git a/backend/src/entities/connection/application/data-structures/test-connection-result.ds.ts b/backend/src/entities/connection/application/data-structures/test-connection-result.ds.ts index 50935167f..d12b7c600 100644 --- a/backend/src/entities/connection/application/data-structures/test-connection-result.ds.ts +++ b/backend/src/entities/connection/application/data-structures/test-connection-result.ds.ts @@ -1,4 +1,4 @@ export class TestConnectionResultDs { - result: boolean; - message: string; + result: boolean; + message: string; } diff --git a/backend/src/entities/connection/application/data-structures/token.ds.ts b/backend/src/entities/connection/application/data-structures/token.ds.ts index 32378bd1a..1bf92c872 100644 --- a/backend/src/entities/connection/application/data-structures/token.ds.ts +++ b/backend/src/entities/connection/application/data-structures/token.ds.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; export class TokenDs { - @ApiProperty() - token: string; + @ApiProperty() + token: string; } diff --git a/backend/src/entities/connection/application/data-structures/unfreeze-connection.ds.ts b/backend/src/entities/connection/application/data-structures/unfreeze-connection.ds.ts index 37c3f7e48..c0cb5c25a 100644 --- a/backend/src/entities/connection/application/data-structures/unfreeze-connection.ds.ts +++ b/backend/src/entities/connection/application/data-structures/unfreeze-connection.ds.ts @@ -1,4 +1,4 @@ export class UnfreezeConnectionDs { - connectionId: string; - userId: string; + connectionId: string; + userId: string; } diff --git a/backend/src/entities/connection/application/data-structures/update-connection.ds.ts b/backend/src/entities/connection/application/data-structures/update-connection.ds.ts index 88fa4a9b1..8fbed81b2 100644 --- a/backend/src/entities/connection/application/data-structures/update-connection.ds.ts +++ b/backend/src/entities/connection/application/data-structures/update-connection.ds.ts @@ -1,31 +1,31 @@ import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; export class UpdateConnectionDs { - connection_parameters: { - title: string; - masterEncryption: boolean; - type: ConnectionTypesEnum; - host: string; - port: number; - username: string; - password: string; - database: string; - schema: string; - sid: string; - ssh: boolean; - privateSSHKey: string; - sshHost: string; - sshPort: number; - sshUsername: string; - ssl: boolean; - cert: string; - azure_encryption: boolean; - authSource: string; - dataCenter: string; - }; - update_info: { - authorId: string; - connectionId: string; - masterPwd: string; - }; + connection_parameters: { + title: string; + masterEncryption: boolean; + type: ConnectionTypesEnum; + host: string; + port: number; + username: string; + password: string; + database: string; + schema: string; + sid: string; + ssh: boolean; + privateSSHKey: string; + sshHost: string; + sshPort: number; + sshUsername: string; + ssl: boolean; + cert: string; + azure_encryption: boolean; + authSource: string; + dataCenter: string; + }; + update_info: { + authorId: string; + connectionId: string; + masterPwd: string; + }; } diff --git a/backend/src/entities/connection/application/data-structures/update-master-password.ds.ts b/backend/src/entities/connection/application/data-structures/update-master-password.ds.ts index e6ddc5a6f..29b0fb7f5 100644 --- a/backend/src/entities/connection/application/data-structures/update-master-password.ds.ts +++ b/backend/src/entities/connection/application/data-structures/update-master-password.ds.ts @@ -1,11 +1,11 @@ import { ApiProperty } from '@nestjs/swagger'; export class UpdateMasterPasswordDs { - connectionId: string; + connectionId: string; - @ApiProperty() - newMasterPwd: string; + @ApiProperty() + newMasterPwd: string; - @ApiProperty() - oldMasterPwd: string; + @ApiProperty() + oldMasterPwd: string; } diff --git a/backend/src/entities/connection/application/data-structures/validate-connection-master-password.ds.ts b/backend/src/entities/connection/application/data-structures/validate-connection-master-password.ds.ts index 2e2503c4f..a3653457c 100644 --- a/backend/src/entities/connection/application/data-structures/validate-connection-master-password.ds.ts +++ b/backend/src/entities/connection/application/data-structures/validate-connection-master-password.ds.ts @@ -1,4 +1,4 @@ export class ValidateConnectionMasterPasswordDs { - connectionId: string; - masterPassword: string; -} \ No newline at end of file + connectionId: string; + masterPassword: string; +} diff --git a/backend/src/entities/connection/application/dto/create-connection.dto.ts b/backend/src/entities/connection/application/dto/create-connection.dto.ts index 1bdac4694..fb9f7686d 100644 --- a/backend/src/entities/connection/application/dto/create-connection.dto.ts +++ b/backend/src/entities/connection/application/dto/create-connection.dto.ts @@ -1,117 +1,117 @@ import { ApiProperty } from '@nestjs/swagger'; -import { IsBoolean, IsEnum, IsNumber, IsOptional, IsString, Max, Min } from 'class-validator'; -import { isTest } from '../../../../helpers/app/is-test.js'; import { - ConnectionTypesEnum, - ConnectionTypeTestEnum, + ConnectionTypesEnum, + ConnectionTypeTestEnum, } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; +import { IsBoolean, IsEnum, IsNumber, IsOptional, IsString, Max, Min } from 'class-validator'; +import { isTest } from '../../../../helpers/app/is-test.js'; export class CreateConnectionDto { - @ApiProperty({ required: false }) - @IsOptional() - @IsString() - title?: string; - - @IsOptional() - @IsBoolean() - @ApiProperty() - masterEncryption: boolean; - - @IsEnum(isTest() ? ConnectionTypeTestEnum : ConnectionTypesEnum) - @ApiProperty() - type: ConnectionTypesEnum; - - @IsOptional() - @IsString() - @ApiProperty() - host: string; - - @IsOptional() - @IsNumber({ maxDecimalPlaces: 0 }) - @Max(65535) - @Min(0) - @ApiProperty() - port: number; - - @IsOptional() - @IsString() - @ApiProperty() - username: string; - - @IsOptional() - @IsString() - @ApiProperty() - password: string; - - @IsOptional() - @IsString() - @ApiProperty() - database: string; - - @IsOptional() - @IsString() - @ApiProperty() - schema: string; - - @IsOptional() - @IsString() - @ApiProperty() - sid?: string; - - @IsOptional() - @IsBoolean() - @ApiProperty({ required: false }) - ssh?: boolean; - - @IsOptional() - @IsString() - @ApiProperty({ required: false }) - privateSSHKey?: string; - - @IsOptional() - @IsString() - @ApiProperty({ required: false }) - sshHost?: string; - - @IsOptional() - @IsNumber({ maxDecimalPlaces: 0 }) - @Max(65535) - @Min(0) - @ApiProperty({ required: false }) - sshPort?: number; - - @IsOptional() - @IsString() - @ApiProperty({ required: false }) - sshUsername?: string; - - @IsOptional() - @IsBoolean() - @ApiProperty({ required: false }) - ssl?: boolean; - - @IsOptional() - @IsString() - @ApiProperty({ required: false }) - cert?: string; - - @IsOptional() - @IsBoolean() - @ApiProperty({ required: false }) - azure_encryption?: boolean; - - @IsOptional() - @IsBoolean() - @ApiProperty({ required: false }) - isTestConnection?: boolean; - - @IsOptional() - @IsString() - @ApiProperty({ required: false }) - authSource?: string; - - @IsOptional() - @IsString() - @ApiProperty({ required: false }) - dataCenter?: string; + @ApiProperty({ required: false }) + @IsOptional() + @IsString() + title?: string; + + @IsOptional() + @IsBoolean() + @ApiProperty() + masterEncryption: boolean; + + @IsEnum(isTest() ? ConnectionTypeTestEnum : ConnectionTypesEnum) + @ApiProperty() + type: ConnectionTypesEnum; + + @IsOptional() + @IsString() + @ApiProperty() + host: string; + + @IsOptional() + @IsNumber({ maxDecimalPlaces: 0 }) + @Max(65535) + @Min(0) + @ApiProperty() + port: number; + + @IsOptional() + @IsString() + @ApiProperty() + username: string; + + @IsOptional() + @IsString() + @ApiProperty() + password: string; + + @IsOptional() + @IsString() + @ApiProperty() + database: string; + + @IsOptional() + @IsString() + @ApiProperty() + schema: string; + + @IsOptional() + @IsString() + @ApiProperty() + sid?: string; + + @IsOptional() + @IsBoolean() + @ApiProperty({ required: false }) + ssh?: boolean; + + @IsOptional() + @IsString() + @ApiProperty({ required: false }) + privateSSHKey?: string; + + @IsOptional() + @IsString() + @ApiProperty({ required: false }) + sshHost?: string; + + @IsOptional() + @IsNumber({ maxDecimalPlaces: 0 }) + @Max(65535) + @Min(0) + @ApiProperty({ required: false }) + sshPort?: number; + + @IsOptional() + @IsString() + @ApiProperty({ required: false }) + sshUsername?: string; + + @IsOptional() + @IsBoolean() + @ApiProperty({ required: false }) + ssl?: boolean; + + @IsOptional() + @IsString() + @ApiProperty({ required: false }) + cert?: string; + + @IsOptional() + @IsBoolean() + @ApiProperty({ required: false }) + azure_encryption?: boolean; + + @IsOptional() + @IsBoolean() + @ApiProperty({ required: false }) + isTestConnection?: boolean; + + @IsOptional() + @IsString() + @ApiProperty({ required: false }) + authSource?: string; + + @IsOptional() + @IsString() + @ApiProperty({ required: false }) + dataCenter?: string; } diff --git a/backend/src/entities/connection/application/dto/create-group-in-connection.dto.ts b/backend/src/entities/connection/application/dto/create-group-in-connection.dto.ts index 4cb61843c..e78c052e1 100644 --- a/backend/src/entities/connection/application/dto/create-group-in-connection.dto.ts +++ b/backend/src/entities/connection/application/dto/create-group-in-connection.dto.ts @@ -2,8 +2,8 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty, IsString } from 'class-validator'; export class CreateGroupInConnectionDTO { - @IsNotEmpty() - @IsString() - @ApiProperty() - title: string; + @IsNotEmpty() + @IsString() + @ApiProperty() + title: string; } diff --git a/backend/src/entities/connection/application/dto/created-connection.dto.ts b/backend/src/entities/connection/application/dto/created-connection.dto.ts index a4b66d8fe..1a7566066 100644 --- a/backend/src/entities/connection/application/dto/created-connection.dto.ts +++ b/backend/src/entities/connection/application/dto/created-connection.dto.ts @@ -1,100 +1,100 @@ import { ApiProperty } from '@nestjs/swagger'; -import { FoundUserDto } from '../../../user/dto/found-user.dto.js'; import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; +import { FoundUserDto } from '../../../user/dto/found-user.dto.js'; export class CreatedGroupInConnectionDTO { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - title: string; + @ApiProperty() + title: string; - @ApiProperty() - isMain: boolean; + @ApiProperty() + isMain: boolean; - @ApiProperty({ isArray: true, type: FoundUserDto }) - users: Array; + @ApiProperty({ isArray: true, type: FoundUserDto }) + users: Array; } export class CreatedConnectionDTO { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - title: string; + @ApiProperty() + title: string; - @ApiProperty() - masterEncryption: boolean; + @ApiProperty() + masterEncryption: boolean; - @ApiProperty({ enum: ConnectionTypesEnum }) - type: ConnectionTypesEnum | string; + @ApiProperty({ enum: ConnectionTypesEnum }) + type: ConnectionTypesEnum | string; - @ApiProperty() - host: string; + @ApiProperty() + host: string; - @ApiProperty() - port: number; + @ApiProperty() + port: number; - @ApiProperty() - username: string; + @ApiProperty() + username: string; - @ApiProperty() - database: string; + @ApiProperty() + database: string; - @ApiProperty() - schema: string; + @ApiProperty() + schema: string; - @ApiProperty() - sid: string; + @ApiProperty() + sid: string; - @ApiProperty() - ssh: boolean; + @ApiProperty() + ssh: boolean; - @ApiProperty() - sshHost: string; + @ApiProperty() + sshHost: string; - @ApiProperty() - sshPort: number; + @ApiProperty() + sshPort: number; - @ApiProperty() - sshUsername: string; + @ApiProperty() + sshUsername: string; - @ApiProperty() - ssl: boolean; + @ApiProperty() + ssl: boolean; - @ApiProperty() - cert: string; + @ApiProperty() + cert: string; - @ApiProperty() - azure_encryption: boolean; + @ApiProperty() + azure_encryption: boolean; - @ApiProperty() - token: string | null; + @ApiProperty() + token: string | null; - @ApiProperty() - createdAt: Date; + @ApiProperty() + createdAt: Date; - @ApiProperty() - updatedAt: Date; + @ApiProperty() + updatedAt: Date; - @ApiProperty() - isTestConnection: boolean; + @ApiProperty() + isTestConnection: boolean; - @ApiProperty() - isFrozen: boolean; + @ApiProperty() + isFrozen: boolean; - @ApiProperty() - author: string; + @ApiProperty() + author: string; - @ApiProperty() - authSource: string; + @ApiProperty() + authSource: string; - @ApiProperty() - dataCenter: string | null; + @ApiProperty() + dataCenter: string | null; - @ApiProperty() - master_hash: string; + @ApiProperty() + master_hash: string; - @ApiProperty({ isArray: true, type: CreatedGroupInConnectionDTO }) - groups: Array; + @ApiProperty({ isArray: true, type: CreatedGroupInConnectionDTO }) + groups: Array; } diff --git a/backend/src/entities/connection/application/dto/delete-connection.dto.ts b/backend/src/entities/connection/application/dto/delete-connection.dto.ts index 8fb297b7b..eb8161128 100644 --- a/backend/src/entities/connection/application/dto/delete-connection.dto.ts +++ b/backend/src/entities/connection/application/dto/delete-connection.dto.ts @@ -2,13 +2,13 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsOptional, IsString } from 'class-validator'; export class DeleteConnectionReasonDto { - @IsOptional() - @IsString() - @ApiProperty() - reason: string; + @IsOptional() + @IsString() + @ApiProperty() + reason: string; - @IsOptional() - @IsString() - @ApiProperty() - message: string; + @IsOptional() + @IsString() + @ApiProperty() + message: string; } diff --git a/backend/src/entities/connection/application/dto/delete-group-from-connection-request.dto.ts b/backend/src/entities/connection/application/dto/delete-group-from-connection-request.dto.ts index 8ca960efd..e48ae6ad1 100644 --- a/backend/src/entities/connection/application/dto/delete-group-from-connection-request.dto.ts +++ b/backend/src/entities/connection/application/dto/delete-group-from-connection-request.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; export class DeleteGroupFromConnectionDTO { - @ApiProperty() - groupId: string; + @ApiProperty() + groupId: string; } diff --git a/backend/src/entities/connection/application/dto/found-user-groups-in-connection.dto.ts b/backend/src/entities/connection/application/dto/found-user-groups-in-connection.dto.ts index eba29ae22..c49277cbf 100644 --- a/backend/src/entities/connection/application/dto/found-user-groups-in-connection.dto.ts +++ b/backend/src/entities/connection/application/dto/found-user-groups-in-connection.dto.ts @@ -3,23 +3,23 @@ import { AccessLevelEnum } from '../../../../enums/access-level.enum.js'; import { SimpleFoundUserInfoDs } from '../../../user/dto/found-user.dto.js'; export class FoundGroupInConnectionDTO { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - title: string; + @ApiProperty() + title: string; - @ApiProperty() - isMain: boolean; + @ApiProperty() + isMain: boolean; - @ApiProperty({ required: false, isArray: true, type: SimpleFoundUserInfoDs }) - users?: Array; + @ApiProperty({ required: false, isArray: true, type: SimpleFoundUserInfoDs }) + users?: Array; } export class FoundUserGroupsInConnectionDTO { - @ApiProperty({ type: FoundGroupInConnectionDTO }) - group: FoundGroupInConnectionDTO; + @ApiProperty({ type: FoundGroupInConnectionDTO }) + group: FoundGroupInConnectionDTO; - @ApiProperty({ enum: AccessLevelEnum }) - accessLevel: AccessLevelEnum; + @ApiProperty({ enum: AccessLevelEnum }) + accessLevel: AccessLevelEnum; } diff --git a/backend/src/entities/connection/application/dto/new-connection-token-response.dto.ts b/backend/src/entities/connection/application/dto/new-connection-token-response.dto.ts index e8625bc1f..4c3cef691 100644 --- a/backend/src/entities/connection/application/dto/new-connection-token-response.dto.ts +++ b/backend/src/entities/connection/application/dto/new-connection-token-response.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; export class ConnectionTokenResponseDTO { - @ApiProperty() - token: string; + @ApiProperty() + token: string; } diff --git a/backend/src/entities/connection/application/dto/test-connection-response.dto.ts b/backend/src/entities/connection/application/dto/test-connection-response.dto.ts index f8a5561b3..d262cd5a2 100644 --- a/backend/src/entities/connection/application/dto/test-connection-response.dto.ts +++ b/backend/src/entities/connection/application/dto/test-connection-response.dto.ts @@ -1,9 +1,9 @@ import { ApiProperty } from '@nestjs/swagger'; export class TestConnectionResponseDTO { - @ApiProperty() - result: boolean; + @ApiProperty() + result: boolean; - @ApiProperty() - message: string; + @ApiProperty() + message: string; } diff --git a/backend/src/entities/connection/application/dto/update-master-password-request-body.dto.ts b/backend/src/entities/connection/application/dto/update-master-password-request-body.dto.ts index ca8d726d5..0219e98de 100644 --- a/backend/src/entities/connection/application/dto/update-master-password-request-body.dto.ts +++ b/backend/src/entities/connection/application/dto/update-master-password-request-body.dto.ts @@ -1,13 +1,13 @@ import { IsNotEmpty, IsString, MaxLength } from 'class-validator'; export class UpdateMasterPasswordRequestBodyDto { - @IsString() - @IsNotEmpty() - @MaxLength(255) - oldMasterPwd: string; + @IsString() + @IsNotEmpty() + @MaxLength(255) + oldMasterPwd: string; - @IsString() - @IsNotEmpty() - @MaxLength(255) - newMasterPwd: string; + @IsString() + @IsNotEmpty() + @MaxLength(255) + newMasterPwd: string; } diff --git a/backend/src/entities/connection/application/dto/updated-connection-responce.dto.ts b/backend/src/entities/connection/application/dto/updated-connection-responce.dto.ts index a8fca079a..fbf4d4a52 100644 --- a/backend/src/entities/connection/application/dto/updated-connection-responce.dto.ts +++ b/backend/src/entities/connection/application/dto/updated-connection-responce.dto.ts @@ -2,6 +2,6 @@ import { ApiProperty } from '@nestjs/swagger'; import { CreatedConnectionDTO } from './created-connection.dto.js'; export class UpdatedConnectionResponseDTO { - @ApiProperty() - connection: Omit; + @ApiProperty() + connection: Omit; } diff --git a/backend/src/entities/connection/application/dto/validation-result.ro.ts b/backend/src/entities/connection/application/dto/validation-result.ro.ts index 9ed5b23cb..4d62c3de9 100644 --- a/backend/src/entities/connection/application/dto/validation-result.ro.ts +++ b/backend/src/entities/connection/application/dto/validation-result.ro.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; export class ValidationResultRo { - @ApiProperty() - isValid: boolean; + @ApiProperty() + isValid: boolean; } diff --git a/backend/src/entities/connection/connection.controller.ts b/backend/src/entities/connection/connection.controller.ts index 3e2aaccc4..d3d351e57 100644 --- a/backend/src/entities/connection/connection.controller.ts +++ b/backend/src/entities/connection/connection.controller.ts @@ -11,10 +11,16 @@ import { UseGuards, UseInterceptors, } from '@nestjs/common'; +import { ApiBearerAuth, ApiBody, ApiOperation, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger'; +import { SkipThrottle } from '@nestjs/throttler'; +import { isRedisConnectionUrl } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; +import { TestConnectionResultDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/test-result-connection.ds.js'; +import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; import validator from 'validator'; import { IGlobalDatabaseContext } from '../../common/application/global-database-context.interface.js'; import { BaseType, UseCaseType } from '../../common/data-injection.tokens.js'; import { BodyUuid, GCLlId, MasterPassword, QueryUuid, SlugUuid, UserId } from '../../decorators/index.js'; +import { Timeout } from '../../decorators/timeout.decorator.js'; import { AmplitudeEventTypeEnum, InTransactionEnum } from '../../enums/index.js'; import { Messages } from '../../exceptions/text/messages.js'; import { processExceptionMessage } from '../../exceptions/utils/process-exception-message.js'; @@ -26,7 +32,9 @@ import { toPrettyErrorsMsg, } from '../../helpers/index.js'; import { SentryInterceptor } from '../../interceptors/index.js'; +import { SuccessResponse } from '../../microservices/saas-microservice/data-structures/common-responce.ds.js'; import { AmplitudeService } from '../amplitude/amplitude.service.js'; +import { FoundGroupResponseDto } from '../group/dto/found-group-response.dto.js'; import { IComplexPermission } from '../permission/permission.interface.js'; import { FindUserDs } from '../user/application/data-structures/find-user.ds.js'; import { FoundUserDto } from '../user/dto/found-user.dto.js'; @@ -36,23 +44,17 @@ import { DeleteConnectionDs } from './application/data-structures/delete-connect import { DeleteGroupInConnectionDs } from './application/data-structures/delete-group-in-connection.ds.js'; import { FindOneConnectionDs } from './application/data-structures/find-one-connection.ds.js'; import { FoundConnectionsDs } from './application/data-structures/found-connections.ds.js'; +import { FoundOneConnectionDs } from './application/data-structures/found-one-connection.ds.js'; +import { FoundPermissionsInConnectionDs } from './application/data-structures/found-permissions-in-connection.ds.js'; import { GetGroupsInConnectionDs } from './application/data-structures/get-groups-in-connection.ds.js'; import { GetPermissionsInConnectionDs } from './application/data-structures/get-permissions-in-connection.ds.js'; import { RestoredConnectionDs } from './application/data-structures/restored-connection.ds.js'; import { UpdateConnectionDs } from './application/data-structures/update-connection.ds.js'; import { UpdateMasterPasswordDs } from './application/data-structures/update-master-password.ds.js'; -import { CreatedConnectionDTO } from './application/dto/created-connection.dto.js'; -import { ApiBearerAuth, ApiBody, ApiOperation, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger'; -import { SkipThrottle } from '@nestjs/throttler'; -import { isRedisConnectionUrl } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; -import { TestConnectionResultDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/test-result-connection.ds.js'; -import { SuccessResponse } from '../../microservices/saas-microservice/data-structures/common-responce.ds.js'; -import { FoundGroupResponseDto } from '../group/dto/found-group-response.dto.js'; -import { FoundOneConnectionDs } from './application/data-structures/found-one-connection.ds.js'; -import { FoundPermissionsInConnectionDs } from './application/data-structures/found-permissions-in-connection.ds.js'; import { ValidateConnectionMasterPasswordDs } from './application/data-structures/validate-connection-master-password.ds.js'; import { CreateConnectionDto } from './application/dto/create-connection.dto.js'; import { CreateGroupInConnectionDTO } from './application/dto/create-group-in-connection.dto.js'; +import { CreatedConnectionDTO } from './application/dto/created-connection.dto.js'; import { DeleteConnectionReasonDto } from './application/dto/delete-connection.dto.js'; import { DeleteGroupFromConnectionDTO } from './application/dto/delete-group-from-connection-request.dto.js'; import { FoundUserGroupsInConnectionDTO } from './application/dto/found-user-groups-in-connection.dto.js'; @@ -82,8 +84,6 @@ import { } from './use-cases/use-cases.interfaces.js'; import { TokenValidationResult } from './use-cases/validate-connection-token.use.case.js'; import { isTestConnectionUtil } from './utils/is-test-connection-util.js'; -import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; -import { Timeout } from '../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/connection/connection.entity.ts b/backend/src/entities/connection/connection.entity.ts index 7349f305b..a6caaae77 100644 --- a/backend/src/entities/connection/connection.entity.ts +++ b/backend/src/entities/connection/connection.entity.ts @@ -1,4 +1,5 @@ import { Expose } from 'class-transformer'; +import { nanoid } from 'nanoid'; import { AfterLoad, BeforeInsert, @@ -12,23 +13,22 @@ import { PrimaryColumn, Relation, } from 'typeorm'; -import { isConnectionTypeAgent } from '../../helpers/index.js'; +import { Constants } from '../../helpers/constants/constants.js'; import { Encryptor } from '../../helpers/encryption/encryptor.js'; +import { isConnectionTypeAgent } from '../../helpers/index.js'; import { AgentEntity } from '../agent/agent.entity.js'; +import { CompanyInfoEntity } from '../company-info/company-info.entity.js'; import { ConnectionPropertiesEntity } from '../connection-properties/connection-properties.entity.js'; import { GroupEntity } from '../group/group.entity.js'; +import { ActionRulesEntity } from '../table-actions/table-action-rules-module/action-rules.entity.js'; +import { TableFiltersEntity } from '../table-filters/table-filters.entity.js'; import { TableInfoEntity } from '../table-info/table-info.entity.js'; import { TableLogsEntity } from '../table-logs/table-logs.entity.js'; import { TableSettingsEntity } from '../table-settings/common-table-settings/table-settings.entity.js'; -import { UserEntity } from '../user/user.entity.js'; -import { CompanyInfoEntity } from '../company-info/company-info.entity.js'; -import { ActionRulesEntity } from '../table-actions/table-action-rules-module/action-rules.entity.js'; -import { nanoid } from 'nanoid'; -import { Constants } from '../../helpers/constants/constants.js'; -import { TableFiltersEntity } from '../table-filters/table-filters.entity.js'; import { PersonalTableSettingsEntity } from '../table-settings/personal-table-settings/personal-table-settings.entity.js'; -import { SavedDbQueryEntity } from '../visualizations/saved-db-query/saved-db-query.entity.js'; +import { UserEntity } from '../user/user.entity.js'; import { DashboardEntity } from '../visualizations/dashboard/dashboard.entity.js'; +import { SavedDbQueryEntity } from '../visualizations/saved-db-query/saved-db-query.entity.js'; @Entity('connection') export class ConnectionEntity { diff --git a/backend/src/entities/connection/connection.module.ts b/backend/src/entities/connection/connection.module.ts index 37722c2ff..442cafe4b 100644 --- a/backend/src/entities/connection/connection.module.ts +++ b/backend/src/entities/connection/connection.module.ts @@ -1,5 +1,6 @@ import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthWithApiMiddleware } from '../../authorization/auth-with-api.middleware.js'; import { AuthMiddleware } from '../../authorization/index.js'; import { GlobalDatabaseContext } from '../../common/application/global-database-context.js'; import { BaseType, UseCaseType } from '../../common/data-injection.tokens.js'; @@ -30,137 +31,136 @@ import { GetUserPermissionsForGroupInConnectionUseCase } from './use-cases/get-u import { RefreshConnectionAgentTokenUseCase } from './use-cases/refresh-connection-agent-token.use.case.js'; import { RestoreConnectionUseCase } from './use-cases/restore-connection-use.case.js'; import { TestConnectionUseCase } from './use-cases/test-connection.use.case.js'; -import { UpdateConnectionMasterPasswordUseCase } from './use-cases/update-connection-master-password.use.case.js'; +import { UnfreezeConnectionUseCase } from './use-cases/unfreeze-connection.use.case.js'; import { UpdateConnectionUseCase } from './use-cases/update-connection.use.case.js'; -import { ValidateConnectionTokenUseCase } from './use-cases/validate-connection-token.use.case.js'; +import { UpdateConnectionMasterPasswordUseCase } from './use-cases/update-connection-master-password.use.case.js'; import { ValidateConnectionMasterPasswordUseCase } from './use-cases/validate-connection-master-password.use.case.js'; -import { AuthWithApiMiddleware } from '../../authorization/auth-with-api.middleware.js'; -import { UnfreezeConnectionUseCase } from './use-cases/unfreeze-connection.use.case.js'; +import { ValidateConnectionTokenUseCase } from './use-cases/validate-connection-token.use.case.js'; @Module({ - imports: [ - TypeOrmModule.forFeature([ - ConnectionEntity, - UserEntity, - GroupEntity, - PermissionEntity, - TableSettingsEntity, - TableLogsEntity, - CustomFieldsEntity, - TableWidgetEntity, - ConnectionPropertiesEntity, - LogOutEntity, - ]), - UserModule, - AgentModule, - AmplitudeModule, - ], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.FIND_CONNECTIONS, - useClass: FindAllConnectionsUseCase, - }, - { - provide: UseCaseType.FIND_CONNECTION, - useClass: FindOneConnectionUseCase, - }, - { - provide: UseCaseType.FIND_USERS_IN_CONNECTION, - useClass: FindAllUsersInConnectionUseCase, - }, - { - provide: UseCaseType.CREATE_CONNECTION, - useClass: CreateConnectionUseCase, - }, - { - provide: UseCaseType.UPDATE_CONNECTION, - useClass: UpdateConnectionUseCase, - }, - { - provide: UseCaseType.DELETE_CONNECTION, - useClass: DeleteConnectionUseCase, - }, - { - provide: UseCaseType.DELETE_GROUP_FROM_CONNECTION, - useClass: DeleteGroupFromConnectionUseCase, - }, - { - provide: UseCaseType.CREATE_GROUP_IN_CONNECTION, - useClass: CreateGroupInConnectionUseCase, - }, - { - provide: UseCaseType.GET_USER_GROUPS_IN_CONNECTION, - useClass: GetUserGroupsInConnectionUseCase, - }, - { - provide: UseCaseType.GET_PERMISSIONS_FOR_GROUP_IN_CONNECTION, - useClass: GetPermissionsForGroupInConnectionUseCase, - }, - { - provide: UseCaseType.GET_USER_PERMISSIONS_FOR_GROUP_IN_CONNECTION, - useClass: GetUserPermissionsForGroupInConnectionUseCase, - }, - { - provide: UseCaseType.TEST_CONNECTION_USE_CASE, - useClass: TestConnectionUseCase, - }, - { - provide: UseCaseType.UPDATE_CONNECTION_MASTER_PASSWORD, - useClass: UpdateConnectionMasterPasswordUseCase, - }, - { - provide: UseCaseType.RESTORE_CONNECTION, - useClass: RestoreConnectionUseCase, - }, - { - provide: UseCaseType.VALIDATE_CONNECTION_TOKEN, - useClass: ValidateConnectionTokenUseCase, - }, - { - provide: UseCaseType.REFRESH_CONNECTION_AGENT_TOKEN, - useClass: RefreshConnectionAgentTokenUseCase, - }, - { - provide: UseCaseType.VALIDATE_CONNECTION_MASTER_PASSWORD, - useClass: ValidateConnectionMasterPasswordUseCase, - }, - { - provide: UseCaseType.UNFREEZE_CONNECTION, - useClass: UnfreezeConnectionUseCase, - }, - ], - controllers: [ConnectionController], + imports: [ + TypeOrmModule.forFeature([ + ConnectionEntity, + UserEntity, + GroupEntity, + PermissionEntity, + TableSettingsEntity, + TableLogsEntity, + CustomFieldsEntity, + TableWidgetEntity, + ConnectionPropertiesEntity, + LogOutEntity, + ]), + UserModule, + AgentModule, + AmplitudeModule, + ], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.FIND_CONNECTIONS, + useClass: FindAllConnectionsUseCase, + }, + { + provide: UseCaseType.FIND_CONNECTION, + useClass: FindOneConnectionUseCase, + }, + { + provide: UseCaseType.FIND_USERS_IN_CONNECTION, + useClass: FindAllUsersInConnectionUseCase, + }, + { + provide: UseCaseType.CREATE_CONNECTION, + useClass: CreateConnectionUseCase, + }, + { + provide: UseCaseType.UPDATE_CONNECTION, + useClass: UpdateConnectionUseCase, + }, + { + provide: UseCaseType.DELETE_CONNECTION, + useClass: DeleteConnectionUseCase, + }, + { + provide: UseCaseType.DELETE_GROUP_FROM_CONNECTION, + useClass: DeleteGroupFromConnectionUseCase, + }, + { + provide: UseCaseType.CREATE_GROUP_IN_CONNECTION, + useClass: CreateGroupInConnectionUseCase, + }, + { + provide: UseCaseType.GET_USER_GROUPS_IN_CONNECTION, + useClass: GetUserGroupsInConnectionUseCase, + }, + { + provide: UseCaseType.GET_PERMISSIONS_FOR_GROUP_IN_CONNECTION, + useClass: GetPermissionsForGroupInConnectionUseCase, + }, + { + provide: UseCaseType.GET_USER_PERMISSIONS_FOR_GROUP_IN_CONNECTION, + useClass: GetUserPermissionsForGroupInConnectionUseCase, + }, + { + provide: UseCaseType.TEST_CONNECTION_USE_CASE, + useClass: TestConnectionUseCase, + }, + { + provide: UseCaseType.UPDATE_CONNECTION_MASTER_PASSWORD, + useClass: UpdateConnectionMasterPasswordUseCase, + }, + { + provide: UseCaseType.RESTORE_CONNECTION, + useClass: RestoreConnectionUseCase, + }, + { + provide: UseCaseType.VALIDATE_CONNECTION_TOKEN, + useClass: ValidateConnectionTokenUseCase, + }, + { + provide: UseCaseType.REFRESH_CONNECTION_AGENT_TOKEN, + useClass: RefreshConnectionAgentTokenUseCase, + }, + { + provide: UseCaseType.VALIDATE_CONNECTION_MASTER_PASSWORD, + useClass: ValidateConnectionMasterPasswordUseCase, + }, + { + provide: UseCaseType.UNFREEZE_CONNECTION, + useClass: UnfreezeConnectionUseCase, + }, + ], + controllers: [ConnectionController], }) export class ConnectionModule implements NestModule { - public configure(consumer: MiddlewareConsumer): any { - consumer - .apply(AuthMiddleware) - .forRoutes( - // { path: 'connections', method: RequestMethod.GET }, - { path: 'connections/author', method: RequestMethod.GET }, - { path: 'connection/one/:connectionId', method: RequestMethod.GET }, - { path: '/connection/users/:connectionId', method: RequestMethod.GET }, - { path: 'connection', method: RequestMethod.POST }, - { path: 'connection/:connectionId', method: RequestMethod.PUT }, - { path: 'connection/delete/:connectionId', method: RequestMethod.PUT }, - { path: 'connection/group/:connectionId', method: RequestMethod.PUT }, - { path: '/connection/group/delete/:connectionId', method: RequestMethod.PUT }, - { path: 'connection/group/:connectionId', method: RequestMethod.POST }, - { path: 'connection/groups/:connectionId', method: RequestMethod.GET }, - { path: '/connection/permissions/', method: RequestMethod.GET }, - { path: '/connection/user/permissions', method: RequestMethod.GET }, - { path: '/connection/test', method: RequestMethod.POST }, - { path: '/connection/encryption/update/:connectionId', method: RequestMethod.PUT }, - { path: '/connection/encryption/restore/:connectionId', method: RequestMethod.PUT }, - { path: '/connection/token/refresh/:connectionId', method: RequestMethod.GET }, - { path: '/connection/masterpwd/verify/:connectionId', method: RequestMethod.GET }, - { path: '/connection/unfreeze/:connectionId', method: RequestMethod.PUT }, - ) - .apply(AuthWithApiMiddleware) - .forRoutes({ path: 'connections', method: RequestMethod.GET }); - } + public configure(consumer: MiddlewareConsumer): any { + consumer + .apply(AuthMiddleware) + .forRoutes( + // { path: 'connections', method: RequestMethod.GET }, + { path: 'connections/author', method: RequestMethod.GET }, + { path: 'connection/one/:connectionId', method: RequestMethod.GET }, + { path: '/connection/users/:connectionId', method: RequestMethod.GET }, + { path: 'connection', method: RequestMethod.POST }, + { path: 'connection/:connectionId', method: RequestMethod.PUT }, + { path: 'connection/delete/:connectionId', method: RequestMethod.PUT }, + { path: 'connection/group/:connectionId', method: RequestMethod.PUT }, + { path: '/connection/group/delete/:connectionId', method: RequestMethod.PUT }, + { path: 'connection/group/:connectionId', method: RequestMethod.POST }, + { path: 'connection/groups/:connectionId', method: RequestMethod.GET }, + { path: '/connection/permissions/', method: RequestMethod.GET }, + { path: '/connection/user/permissions', method: RequestMethod.GET }, + { path: '/connection/test', method: RequestMethod.POST }, + { path: '/connection/encryption/update/:connectionId', method: RequestMethod.PUT }, + { path: '/connection/encryption/restore/:connectionId', method: RequestMethod.PUT }, + { path: '/connection/token/refresh/:connectionId', method: RequestMethod.GET }, + { path: '/connection/masterpwd/verify/:connectionId', method: RequestMethod.GET }, + { path: '/connection/unfreeze/:connectionId', method: RequestMethod.PUT }, + ) + .apply(AuthWithApiMiddleware) + .forRoutes({ path: 'connections', method: RequestMethod.GET }); + } } diff --git a/backend/src/entities/connection/repository/connection.repository.interface.ts b/backend/src/entities/connection/repository/connection.repository.interface.ts index 251f8a723..1e239c4b5 100644 --- a/backend/src/entities/connection/repository/connection.repository.interface.ts +++ b/backend/src/entities/connection/repository/connection.repository.interface.ts @@ -2,45 +2,45 @@ import { UserEntity } from '../../user/user.entity.js'; import { ConnectionEntity } from '../connection.entity.js'; export interface IConnectionRepository { - saveNewConnection(connection: ConnectionEntity): Promise; + saveNewConnection(connection: ConnectionEntity): Promise; - findAllUserConnections(userId: string, includeTestConnections: boolean): Promise>; + findAllUserConnections(userId: string, includeTestConnections: boolean): Promise>; - findAllUserNonTestsConnections(userId: string): Promise>; + findAllUserNonTestsConnections(userId: string): Promise>; - findAllUsersInConnection(connectionId): Promise>; + findAllUsersInConnection(connectionId): Promise>; - findOneConnection(connectionId: string): Promise; + findOneConnection(connectionId: string): Promise; - findAndDecryptConnection(connectionId: string, masterPwd: string): Promise; + findAndDecryptConnection(connectionId: string, masterPwd: string): Promise; - removeConnection(connection: ConnectionEntity): Promise; + removeConnection(connection: ConnectionEntity): Promise; - findConnectionWithGroups(connectionId: string): Promise; + findConnectionWithGroups(connectionId: string): Promise; - getWorkedConnectionsInTwoWeeks(): Promise>; + getWorkedConnectionsInTwoWeeks(): Promise>; - getConnectionByGroupIdWithCompanyAndUsersInCompany(groupId: string): Promise; + getConnectionByGroupIdWithCompanyAndUsersInCompany(groupId: string): Promise; - findOneById(connectionId: string): Promise; + findOneById(connectionId: string): Promise; - isTestConnectionById(connectionId: string): Promise; + isTestConnectionById(connectionId: string): Promise; - saveUpdatedConnection(connection: ConnectionEntity): Promise; + saveUpdatedConnection(connection: ConnectionEntity): Promise; - findOneAgentConnectionByToken(connectionToken: string): Promise; + findOneAgentConnectionByToken(connectionToken: string): Promise; - decryptConnectionField(field: string): string; + decryptConnectionField(field: string): string; - findAllUserTestConnections(userId: string): Promise>; + findAllUserTestConnections(userId: string): Promise>; - isUserFromConnection(userId: string, connectionId: string): Promise; + isUserFromConnection(userId: string, connectionId: string): Promise; - findAllCompanyUsersNonTestsConnections(companyId: string): Promise>; + findAllCompanyUsersNonTestsConnections(companyId: string): Promise>; - freezeConnections(connectionsIds: Array): Promise; + freezeConnections(connectionsIds: Array): Promise; - unFreezeConnections(connectionsIds: Array): Promise; + unFreezeConnections(connectionsIds: Array): Promise; - foundUserTestConnectionsWithoutCompany(userId: string): Promise>; + foundUserTestConnectionsWithoutCompany(userId: string): Promise>; } diff --git a/backend/src/entities/connection/repository/custom-connection-repository-extension.ts b/backend/src/entities/connection/repository/custom-connection-repository-extension.ts index ff15fe559..47e210055 100644 --- a/backend/src/entities/connection/repository/custom-connection-repository-extension.ts +++ b/backend/src/entities/connection/repository/custom-connection-repository-extension.ts @@ -8,219 +8,219 @@ import { isTestConnectionUtil } from '../utils/is-test-connection-util.js'; import { IConnectionRepository } from './connection.repository.interface.js'; export const customConnectionRepositoryExtension: IConnectionRepository = { - async saveNewConnection(connection: ConnectionEntity): Promise { - const savedConnection = await this.save(connection); - if (!isConnectionTypeAgent(savedConnection.type)) { - savedConnection.host = this.decryptConnectionField(savedConnection.host); - savedConnection.database = this.decryptConnectionField(savedConnection.database); - savedConnection.password = this.decryptConnectionField(savedConnection.password); - savedConnection.username = this.decryptConnectionField(savedConnection.username); - if (savedConnection.ssh) { - savedConnection.privateSSHKey = this.decryptConnectionField(savedConnection.privateSSHKey); - savedConnection.sshHost = this.decryptConnectionField(savedConnection.sshHost); - savedConnection.sshUsername = this.decryptConnectionField(savedConnection.sshUsername); - } - if (savedConnection.ssl && savedConnection.cert) { - savedConnection.cert = this.decryptConnectionField(savedConnection.cert); - } - } - return savedConnection; - }, - - async findAllUserConnections(userId: string, includeTestConnections: boolean): Promise> { - const connectionQb = this.createQueryBuilder('connection') - .leftJoinAndSelect('connection.groups', 'group') - .leftJoinAndSelect('group.users', 'user') - .leftJoinAndSelect('connection.connection_properties', 'connection_properties') - .andWhere('user.id = :userId', { userId: userId }); - if (!includeTestConnections) { - connectionQb.andWhere('connection.isTestConnection = :isTest', { isTest: false }); - } - return await connectionQb.getMany(); - }, - - async findAllUserTestConnections(userId: string): Promise> { - const connectionQb = this.createQueryBuilder('connection') - .leftJoinAndSelect('connection.groups', 'group') - .leftJoinAndSelect('group.users', 'user') - .leftJoinAndSelect('connection.connection_properties', 'connection_properties') - .andWhere('user.id = :userId', { userId: userId }) - .andWhere('connection.isTestConnection = :isTest', { isTest: true }); - return await connectionQb.getMany(); - }, - - async findAllUserNonTestsConnections(userId: string): Promise> { - const connectionQb = this.createQueryBuilder('connection') - .leftJoinAndSelect('connection.groups', 'group') - .leftJoinAndSelect('group.users', 'user') - .andWhere('user.id = :userId', { userId: userId }) - .andWhere('connection.isTestConnection = :isTest', { isTest: false }); - return await connectionQb.getMany(); - }, - - async findAllUsersInConnection(connectionId: string): Promise> { - const usersQb = this.manager - .getRepository(UserEntity) - .createQueryBuilder('user') - .leftJoinAndSelect('user.groups', 'group') - .leftJoinAndSelect('group.connection', 'connection') - .andWhere('connection.id = :connectionId', { - connectionId: connectionId, - }); - return await usersQb.getMany(); - }, - - async findOneConnection(connectionId: string): Promise { - const connectionQb = this.createQueryBuilder('connection') - .leftJoinAndSelect('connection.connection_properties', 'connection_properties') - .where('connection.id = :connectionId', { - connectionId: connectionId, - }); - const connection = await connectionQb.getOne(); - if (!connection) { - return null; - } - if (!connection.signing_key) { - connection.signing_key = Encryptor.generateRandomString(40); - await this.save(connection); - } - return connection; - }, - - async findAndDecryptConnection(connectionId: string, masterPwd: string): Promise { - const qb = this.createQueryBuilder('connection') - .leftJoinAndSelect('connection.agent', 'agent') - .andWhere('connection.id = :connectionId', { connectionId: connectionId }); - let connection = await qb.getOne(); - if (!connection) { - return null; - } - if (!connection.signing_key) { - connection.signing_key = Encryptor.generateRandomString(40); - await this.save(connection); - } - - if (connection.masterEncryption && !masterPwd) { - throw new Error(Messages.MASTER_PASSWORD_MISSING); - } - - if (connection.masterEncryption && masterPwd) { - if (connection.master_hash) { - const isMasterPwdCorrect = await Encryptor.verifyUserPassword(masterPwd, connection.master_hash); - if (!isMasterPwdCorrect) { - throw new Error(Messages.MASTER_PASSWORD_INCORRECT); - } - } - connection = Encryptor.decryptConnectionCredentials(connection, masterPwd); - } - return connection; - }, - - async removeConnection(connection: ConnectionEntity): Promise { - return await this.remove(connection); - }, - - async findConnectionWithGroups(connectionId: string): Promise { - const qb = this.createQueryBuilder('connection') - .leftJoinAndSelect('connection.groups', 'group') - .andWhere('connection.id = :connectionId', { connectionId: connectionId }); - return await qb.getOne(); - }, - - async getWorkedConnectionsInTwoWeeks(): Promise> { - const freshNonTestConnectionsWithLogs = await this.createQueryBuilder('connection') - .leftJoinAndSelect('connection.author', 'author') - .leftJoin('connection.logs', 'logs') - .where('connection.createdAt > :date', { date: Constants.TWO_WEEKS_AGO() }) - .andWhere('author.gclid IS NOT NULL') - .andWhere('connection.isTestConnection = :isTest', { isTest: false }) - .andWhere('logs.id IS NOT NULL') - .getMany(); - return freshNonTestConnectionsWithLogs; - }, - - async getConnectionByGroupIdWithCompanyAndUsersInCompany(groupId: string): Promise { - const qb = this.createQueryBuilder('connection') - .leftJoinAndSelect('connection.groups', 'group') - .leftJoinAndSelect('connection.company', 'company') - .leftJoinAndSelect('company.users', 'user'); - qb.andWhere('group.id = :groupId', { groupId: groupId }); - return await qb.getOne(); - }, - - async findOneById(connectionId: string): Promise { - return await this.findOne({ where: { id: connectionId } }); - }, - - async findOneAgentConnectionByToken(connectionToken: string): Promise { - const qb = this.createQueryBuilder('connection').leftJoinAndSelect('connection.agent', 'agent'); - qb.andWhere('agent.token = :agentToken', { agentToken: connectionToken }); - return await qb.getOne(); - }, - - async isTestConnectionById(connectionId: string): Promise { - const qb = this.createQueryBuilder('connection').where('connection.id = :connectionId', { - connectionId: connectionId, - }); - const foundConnection = await qb.getOne(); - return isTestConnectionUtil(foundConnection); - }, - - async saveUpdatedConnection(connection: ConnectionEntity): Promise { - return this.save(connection); - }, - - async isUserFromConnection(userId: string, connectionId: string): Promise { - const qb = this.createQueryBuilder('connection') - .leftJoin('connection.groups', 'group') - .leftJoin('group.users', 'user') - .andWhere('user.id = :userId', { userId: userId }) - .andWhere('connection.id = :connectionId', { connectionId: connectionId }); - const foundConnection = await qb.getOne(); - return !!foundConnection; - }, - - async findAllCompanyUsersNonTestsConnections(companyId: string): Promise> { - const connectionQb = this.createQueryBuilder('connection') - .leftJoin('connection.groups', 'group') - .leftJoin('group.users', 'user') - .leftJoin('user.company', 'company') - .leftJoinAndSelect('connection.connection_properties', 'connection_properties') - .where('connection.isTestConnection = :isTest', { isTest: false }) - .andWhere('company.id = :companyId', { companyId: companyId }); - return await connectionQb.getMany(); - }, - - async freezeConnections(connectionsIds: Array): Promise { - await this.createQueryBuilder() - .update(ConnectionEntity) - .set({ is_frozen: true }) - .where('id IN (:...connectionsIds)', { connectionsIds }) - .execute(); - }, - - async unFreezeConnections(connectionsIds: Array): Promise { - await this.createQueryBuilder() - .update(ConnectionEntity) - .set({ is_frozen: false }) - .where('id IN (:...connectionsIds)', { connectionsIds }) - .execute(); - }, - - async foundUserTestConnectionsWithoutCompany(userId: string): Promise> { - const qb = this.createQueryBuilder('connection') - .leftJoin('connection.author', 'user') - .where('user.id = :userId', { userId: userId }) - .andWhere('connection.isTestConnection = :isTest', { isTest: true }) - .andWhere('connection.company IS NULL'); - return await qb.getMany(); - }, - - decryptConnectionField(field: string): string { - try { - return Encryptor.decryptData(field); - } catch (_e) { - return field; - } - }, + async saveNewConnection(connection: ConnectionEntity): Promise { + const savedConnection = await this.save(connection); + if (!isConnectionTypeAgent(savedConnection.type)) { + savedConnection.host = this.decryptConnectionField(savedConnection.host); + savedConnection.database = this.decryptConnectionField(savedConnection.database); + savedConnection.password = this.decryptConnectionField(savedConnection.password); + savedConnection.username = this.decryptConnectionField(savedConnection.username); + if (savedConnection.ssh) { + savedConnection.privateSSHKey = this.decryptConnectionField(savedConnection.privateSSHKey); + savedConnection.sshHost = this.decryptConnectionField(savedConnection.sshHost); + savedConnection.sshUsername = this.decryptConnectionField(savedConnection.sshUsername); + } + if (savedConnection.ssl && savedConnection.cert) { + savedConnection.cert = this.decryptConnectionField(savedConnection.cert); + } + } + return savedConnection; + }, + + async findAllUserConnections(userId: string, includeTestConnections: boolean): Promise> { + const connectionQb = this.createQueryBuilder('connection') + .leftJoinAndSelect('connection.groups', 'group') + .leftJoinAndSelect('group.users', 'user') + .leftJoinAndSelect('connection.connection_properties', 'connection_properties') + .andWhere('user.id = :userId', { userId: userId }); + if (!includeTestConnections) { + connectionQb.andWhere('connection.isTestConnection = :isTest', { isTest: false }); + } + return await connectionQb.getMany(); + }, + + async findAllUserTestConnections(userId: string): Promise> { + const connectionQb = this.createQueryBuilder('connection') + .leftJoinAndSelect('connection.groups', 'group') + .leftJoinAndSelect('group.users', 'user') + .leftJoinAndSelect('connection.connection_properties', 'connection_properties') + .andWhere('user.id = :userId', { userId: userId }) + .andWhere('connection.isTestConnection = :isTest', { isTest: true }); + return await connectionQb.getMany(); + }, + + async findAllUserNonTestsConnections(userId: string): Promise> { + const connectionQb = this.createQueryBuilder('connection') + .leftJoinAndSelect('connection.groups', 'group') + .leftJoinAndSelect('group.users', 'user') + .andWhere('user.id = :userId', { userId: userId }) + .andWhere('connection.isTestConnection = :isTest', { isTest: false }); + return await connectionQb.getMany(); + }, + + async findAllUsersInConnection(connectionId: string): Promise> { + const usersQb = this.manager + .getRepository(UserEntity) + .createQueryBuilder('user') + .leftJoinAndSelect('user.groups', 'group') + .leftJoinAndSelect('group.connection', 'connection') + .andWhere('connection.id = :connectionId', { + connectionId: connectionId, + }); + return await usersQb.getMany(); + }, + + async findOneConnection(connectionId: string): Promise { + const connectionQb = this.createQueryBuilder('connection') + .leftJoinAndSelect('connection.connection_properties', 'connection_properties') + .where('connection.id = :connectionId', { + connectionId: connectionId, + }); + const connection = await connectionQb.getOne(); + if (!connection) { + return null; + } + if (!connection.signing_key) { + connection.signing_key = Encryptor.generateRandomString(40); + await this.save(connection); + } + return connection; + }, + + async findAndDecryptConnection(connectionId: string, masterPwd: string): Promise { + const qb = this.createQueryBuilder('connection') + .leftJoinAndSelect('connection.agent', 'agent') + .andWhere('connection.id = :connectionId', { connectionId: connectionId }); + let connection = await qb.getOne(); + if (!connection) { + return null; + } + if (!connection.signing_key) { + connection.signing_key = Encryptor.generateRandomString(40); + await this.save(connection); + } + + if (connection.masterEncryption && !masterPwd) { + throw new Error(Messages.MASTER_PASSWORD_MISSING); + } + + if (connection.masterEncryption && masterPwd) { + if (connection.master_hash) { + const isMasterPwdCorrect = await Encryptor.verifyUserPassword(masterPwd, connection.master_hash); + if (!isMasterPwdCorrect) { + throw new Error(Messages.MASTER_PASSWORD_INCORRECT); + } + } + connection = Encryptor.decryptConnectionCredentials(connection, masterPwd); + } + return connection; + }, + + async removeConnection(connection: ConnectionEntity): Promise { + return await this.remove(connection); + }, + + async findConnectionWithGroups(connectionId: string): Promise { + const qb = this.createQueryBuilder('connection') + .leftJoinAndSelect('connection.groups', 'group') + .andWhere('connection.id = :connectionId', { connectionId: connectionId }); + return await qb.getOne(); + }, + + async getWorkedConnectionsInTwoWeeks(): Promise> { + const freshNonTestConnectionsWithLogs = await this.createQueryBuilder('connection') + .leftJoinAndSelect('connection.author', 'author') + .leftJoin('connection.logs', 'logs') + .where('connection.createdAt > :date', { date: Constants.TWO_WEEKS_AGO() }) + .andWhere('author.gclid IS NOT NULL') + .andWhere('connection.isTestConnection = :isTest', { isTest: false }) + .andWhere('logs.id IS NOT NULL') + .getMany(); + return freshNonTestConnectionsWithLogs; + }, + + async getConnectionByGroupIdWithCompanyAndUsersInCompany(groupId: string): Promise { + const qb = this.createQueryBuilder('connection') + .leftJoinAndSelect('connection.groups', 'group') + .leftJoinAndSelect('connection.company', 'company') + .leftJoinAndSelect('company.users', 'user'); + qb.andWhere('group.id = :groupId', { groupId: groupId }); + return await qb.getOne(); + }, + + async findOneById(connectionId: string): Promise { + return await this.findOne({ where: { id: connectionId } }); + }, + + async findOneAgentConnectionByToken(connectionToken: string): Promise { + const qb = this.createQueryBuilder('connection').leftJoinAndSelect('connection.agent', 'agent'); + qb.andWhere('agent.token = :agentToken', { agentToken: connectionToken }); + return await qb.getOne(); + }, + + async isTestConnectionById(connectionId: string): Promise { + const qb = this.createQueryBuilder('connection').where('connection.id = :connectionId', { + connectionId: connectionId, + }); + const foundConnection = await qb.getOne(); + return isTestConnectionUtil(foundConnection); + }, + + async saveUpdatedConnection(connection: ConnectionEntity): Promise { + return this.save(connection); + }, + + async isUserFromConnection(userId: string, connectionId: string): Promise { + const qb = this.createQueryBuilder('connection') + .leftJoin('connection.groups', 'group') + .leftJoin('group.users', 'user') + .andWhere('user.id = :userId', { userId: userId }) + .andWhere('connection.id = :connectionId', { connectionId: connectionId }); + const foundConnection = await qb.getOne(); + return !!foundConnection; + }, + + async findAllCompanyUsersNonTestsConnections(companyId: string): Promise> { + const connectionQb = this.createQueryBuilder('connection') + .leftJoin('connection.groups', 'group') + .leftJoin('group.users', 'user') + .leftJoin('user.company', 'company') + .leftJoinAndSelect('connection.connection_properties', 'connection_properties') + .where('connection.isTestConnection = :isTest', { isTest: false }) + .andWhere('company.id = :companyId', { companyId: companyId }); + return await connectionQb.getMany(); + }, + + async freezeConnections(connectionsIds: Array): Promise { + await this.createQueryBuilder() + .update(ConnectionEntity) + .set({ is_frozen: true }) + .where('id IN (:...connectionsIds)', { connectionsIds }) + .execute(); + }, + + async unFreezeConnections(connectionsIds: Array): Promise { + await this.createQueryBuilder() + .update(ConnectionEntity) + .set({ is_frozen: false }) + .where('id IN (:...connectionsIds)', { connectionsIds }) + .execute(); + }, + + async foundUserTestConnectionsWithoutCompany(userId: string): Promise> { + const qb = this.createQueryBuilder('connection') + .leftJoin('connection.author', 'user') + .where('user.id = :userId', { userId: userId }) + .andWhere('connection.isTestConnection = :isTest', { isTest: true }) + .andWhere('connection.company IS NULL'); + return await qb.getMany(); + }, + + decryptConnectionField(field: string): string { + try { + return Encryptor.decryptData(field); + } catch (_e) { + return field; + } + }, }; diff --git a/backend/src/entities/connection/ssl-certificate/read-certificate.ts b/backend/src/entities/connection/ssl-certificate/read-certificate.ts index 1eaf462e4..b1f42e6c0 100644 --- a/backend/src/entities/connection/ssl-certificate/read-certificate.ts +++ b/backend/src/entities/connection/ssl-certificate/read-certificate.ts @@ -1,22 +1,22 @@ import fs from 'fs'; -import path from 'path'; +import path, { join } from 'path'; import { fileURLToPath } from 'url'; -import { join } from 'path'; + const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); export async function readSslCertificate(): Promise { - const fileName = 'global-bundle.pem'; - return new Promise((resolve, reject) => { - fs.readFile( - join(__dirname, '..', '..', '..', '..', '..', 'files', 'certificates', fileName), - 'utf8', - (err, data) => { - if (err) { - reject(err); - } - resolve(data); - }, - ); - }); + const fileName = 'global-bundle.pem'; + return new Promise((resolve, reject) => { + fs.readFile( + join(__dirname, '..', '..', '..', '..', '..', 'files', 'certificates', fileName), + 'utf8', + (err, data) => { + if (err) { + reject(err); + } + resolve(data); + }, + ); + }); } diff --git a/backend/src/entities/connection/use-cases/create-group-in-connection.use.case.ts b/backend/src/entities/connection/use-cases/create-group-in-connection.use.case.ts index 127770188..ed49bc123 100644 --- a/backend/src/entities/connection/use-cases/create-group-in-connection.use.case.ts +++ b/backend/src/entities/connection/use-cases/create-group-in-connection.use.case.ts @@ -3,36 +3,36 @@ import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { FoundGroupResponseDto } from '../../group/dto/found-group-response.dto.js'; +import { buildFoundGroupResponseDto } from '../../group/utils/biuld-found-group-response.dto.js'; import { CreateGroupInConnectionDs } from '../application/data-structures/create-group-in-connection.ds.js'; import { buildNewGroupEntityForConnectionWithUser } from '../utils/build-new-group-entity-for-connection-with-user.js'; import { ICreateGroupInConnection } from './use-cases.interfaces.js'; -import { buildFoundGroupResponseDto } from '../../group/utils/biuld-found-group-response.dto.js'; -import { FoundGroupResponseDto } from '../../group/dto/found-group-response.dto.js'; @Injectable({ scope: Scope.REQUEST }) export class CreateGroupInConnectionUseCase - extends AbstractUseCase - implements ICreateGroupInConnection + extends AbstractUseCase + implements ICreateGroupInConnection { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: CreateGroupInConnectionDs): Promise { - const { - group_parameters: { connectionId, title }, - creation_info: { cognitoUserName }, - } = inputData; - const connectionToUpdate = await this._dbContext.connectionRepository.findConnectionWithGroups(connectionId); - if (connectionToUpdate.groups.find((group) => group.title === title)) { - throw new BadRequestException(Messages.GROUP_NAME_UNIQUE); - } - const foundUser = await this._dbContext.userRepository.findOneUserById(cognitoUserName); - const newGroupEntity = buildNewGroupEntityForConnectionWithUser(connectionToUpdate, foundUser, title); - const savedGroup = await this._dbContext.groupRepository.saveNewOrUpdatedGroup(newGroupEntity); - return buildFoundGroupResponseDto(savedGroup); - } + protected async implementation(inputData: CreateGroupInConnectionDs): Promise { + const { + group_parameters: { connectionId, title }, + creation_info: { cognitoUserName }, + } = inputData; + const connectionToUpdate = await this._dbContext.connectionRepository.findConnectionWithGroups(connectionId); + if (connectionToUpdate.groups.find((group) => group.title === title)) { + throw new BadRequestException(Messages.GROUP_NAME_UNIQUE); + } + const foundUser = await this._dbContext.userRepository.findOneUserById(cognitoUserName); + const newGroupEntity = buildNewGroupEntityForConnectionWithUser(connectionToUpdate, foundUser, title); + const savedGroup = await this._dbContext.groupRepository.saveNewOrUpdatedGroup(newGroupEntity); + return buildFoundGroupResponseDto(savedGroup); + } } diff --git a/backend/src/entities/connection/use-cases/delete-connection.use.case.ts b/backend/src/entities/connection/use-cases/delete-connection.use.case.ts index fb8742144..8488f9e4c 100644 --- a/backend/src/entities/connection/use-cases/delete-connection.use.case.ts +++ b/backend/src/entities/connection/use-cases/delete-connection.use.case.ts @@ -3,38 +3,38 @@ import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; -import { CreatedConnectionDTO } from '../application/dto/created-connection.dto.js'; import { DeleteConnectionDs } from '../application/data-structures/delete-connection.ds.js'; +import { CreatedConnectionDTO } from '../application/dto/created-connection.dto.js'; import { buildCreatedConnectionDs } from '../utils/build-created-connection.ds.js'; import { IDeleteConnection } from './use-cases.interfaces.js'; @Injectable({ scope: Scope.REQUEST }) export class DeleteConnectionUseCase - extends AbstractUseCase - implements IDeleteConnection + extends AbstractUseCase + implements IDeleteConnection { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: DeleteConnectionDs): Promise { - const connectionToDelete = await this._dbContext.connectionRepository.findAndDecryptConnection( - inputData.connectionId, - inputData.masterPwd, - ); - if (!connectionToDelete) { - throw new NotFoundException(Messages.CONNECTION_NOT_FOUND); - } - const userNonTestConnections = await this._dbContext.connectionRepository.findAllUserNonTestsConnections( - inputData.cognitoUserName, - ); - if (userNonTestConnections.length === 0) { - throw new BadRequestException(Messages.DONT_HAVE_NON_TEST_CONNECTIONS); - } - const result = await this._dbContext.connectionRepository.removeConnection(connectionToDelete); - return buildCreatedConnectionDs(result, null, inputData.masterPwd); - } + protected async implementation(inputData: DeleteConnectionDs): Promise { + const connectionToDelete = await this._dbContext.connectionRepository.findAndDecryptConnection( + inputData.connectionId, + inputData.masterPwd, + ); + if (!connectionToDelete) { + throw new NotFoundException(Messages.CONNECTION_NOT_FOUND); + } + const userNonTestConnections = await this._dbContext.connectionRepository.findAllUserNonTestsConnections( + inputData.cognitoUserName, + ); + if (userNonTestConnections.length === 0) { + throw new BadRequestException(Messages.DONT_HAVE_NON_TEST_CONNECTIONS); + } + const result = await this._dbContext.connectionRepository.removeConnection(connectionToDelete); + return buildCreatedConnectionDs(result, null, inputData.masterPwd); + } } diff --git a/backend/src/entities/connection/use-cases/delete-group-from-connection.use.case.ts b/backend/src/entities/connection/use-cases/delete-group-from-connection.use.case.ts index e25b620c4..7a2472157 100644 --- a/backend/src/entities/connection/use-cases/delete-group-from-connection.use.case.ts +++ b/backend/src/entities/connection/use-cases/delete-group-from-connection.use.case.ts @@ -3,35 +3,35 @@ import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { FoundGroupResponseDto } from '../../group/dto/found-group-response.dto.js'; +import { buildFoundGroupResponseDto } from '../../group/utils/biuld-found-group-response.dto.js'; import { DeleteGroupInConnectionDs } from '../application/data-structures/delete-group-in-connection.ds.js'; import { IDeleteGroupInConnection } from './use-cases.interfaces.js'; -import { buildFoundGroupResponseDto } from '../../group/utils/biuld-found-group-response.dto.js'; -import { FoundGroupResponseDto } from '../../group/dto/found-group-response.dto.js'; @Injectable({ scope: Scope.REQUEST }) export class DeleteGroupFromConnectionUseCase - extends AbstractUseCase - implements IDeleteGroupInConnection + extends AbstractUseCase + implements IDeleteGroupInConnection { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: DeleteGroupInConnectionDs): Promise { - const groupToDelete = await this._dbContext.groupRepository.findGroupInConnection( - inputData.groupId, - inputData.connectionId, - ); - if (!groupToDelete) { - throw new BadRequestException(Messages.GROUP_NOT_FOUND); - } - if (groupToDelete.isMain) { - throw new ForbiddenException(Messages.CANT_DELETE_ADMIN_GROUP); - } - const removedGroup = await this._dbContext.groupRepository.removeGroupEntity(groupToDelete); - return buildFoundGroupResponseDto(removedGroup); - } + protected async implementation(inputData: DeleteGroupInConnectionDs): Promise { + const groupToDelete = await this._dbContext.groupRepository.findGroupInConnection( + inputData.groupId, + inputData.connectionId, + ); + if (!groupToDelete) { + throw new BadRequestException(Messages.GROUP_NOT_FOUND); + } + if (groupToDelete.isMain) { + throw new ForbiddenException(Messages.CANT_DELETE_ADMIN_GROUP); + } + const removedGroup = await this._dbContext.groupRepository.removeGroupEntity(groupToDelete); + return buildFoundGroupResponseDto(removedGroup); + } } diff --git a/backend/src/entities/connection/use-cases/find-all-connections.use.case.ts b/backend/src/entities/connection/use-cases/find-all-connections.use.case.ts index bb54188ae..e05edce7c 100644 --- a/backend/src/entities/connection/use-cases/find-all-connections.use.case.ts +++ b/backend/src/entities/connection/use-cases/find-all-connections.use.case.ts @@ -3,22 +3,22 @@ import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { AccessLevelEnum, AmplitudeEventTypeEnum } from '../../../enums/index.js'; +import { Messages } from '../../../exceptions/text/messages.js'; +import { isSaaS } from '../../../helpers/app/is-saas.js'; import { Constants } from '../../../helpers/constants/constants.js'; import { AmplitudeService } from '../../amplitude/amplitude.service.js'; +import { GroupEntity } from '../../group/group.entity.js'; +import { PermissionEntity } from '../../permission/permission.entity.js'; import { CreateUserDs } from '../../user/application/data-structures/create-user.ds.js'; import { FindUserDs } from '../../user/application/data-structures/find-user.ds.js'; -import { FoundConnectionsDs } from '../application/data-structures/found-connections.ds.js'; -import { IFindConnections } from './use-cases.interfaces.js'; -import { Messages } from '../../../exceptions/text/messages.js'; -import { ConnectionEntity } from '../connection.entity.js'; -import { buildFoundConnectionDs } from '../utils/build-found-connection.ds.js'; +import { UserRoleEnum } from '../../user/enums/user-role.enum.js'; import { buildConnectionEntitiesFromTestDtos } from '../../user/utils/build-connection-entities-from-test-dtos.js'; -import { GroupEntity } from '../../group/group.entity.js'; -import { PermissionEntity } from '../../permission/permission.entity.js'; import { buildDefaultAdminGroups } from '../../user/utils/build-default-admin-groups.js'; import { buildDefaultAdminPermissions } from '../../user/utils/build-default-admin-permissions.js'; -import { isSaaS } from '../../../helpers/app/is-saas.js'; -import { UserRoleEnum } from '../../user/enums/user-role.enum.js'; +import { FoundConnectionsDs } from '../application/data-structures/found-connections.ds.js'; +import { ConnectionEntity } from '../connection.entity.js'; +import { buildFoundConnectionDs } from '../utils/build-found-connection.ds.js'; +import { IFindConnections } from './use-cases.interfaces.js'; export type RequiredConnectionKeys = Pick; export type OptionalConnectionKeys = Partial>; @@ -26,116 +26,116 @@ export type FilteredConnection = RequiredConnectionKeys & OptionalConnectionKeys @Injectable() export class FindAllConnectionsUseCase - extends AbstractUseCase - implements IFindConnections + extends AbstractUseCase + implements IFindConnections { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private amplitudeService: AmplitudeService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private amplitudeService: AmplitudeService, + ) { + super(); + } - protected async implementation(userData: CreateUserDs | FindUserDs): Promise { - const user = await this._dbContext.userRepository.findOneUserByIdWithCompany(userData.id); - if (!user) { - throw new InternalServerErrorException(Messages.USER_NOT_FOUND); - } - let allFoundUserConnections: Array = []; + protected async implementation(userData: CreateUserDs | FindUserDs): Promise { + const user = await this._dbContext.userRepository.findOneUserByIdWithCompany(userData.id); + if (!user) { + throw new InternalServerErrorException(Messages.USER_NOT_FOUND); + } + let allFoundUserConnections: Array = []; - if (user.role === UserRoleEnum.ADMIN) { - const allCompanyConnections = await this._dbContext.connectionRepository.findAllCompanyUsersNonTestsConnections( - user.company.id, - ); - allFoundUserConnections = allCompanyConnections; - } else { - allFoundUserConnections = await this._dbContext.connectionRepository.findAllUserConnections(user.id, false); - } + if (user.role === UserRoleEnum.ADMIN) { + const allCompanyConnections = await this._dbContext.connectionRepository.findAllCompanyUsersNonTestsConnections( + user.company.id, + ); + allFoundUserConnections = allCompanyConnections; + } else { + allFoundUserConnections = await this._dbContext.connectionRepository.findAllUserConnections(user.id, false); + } - if (user.showTestConnections && isSaaS() && user.company.show_test_connections) { - let allFoundUserTestConnections = await this._dbContext.connectionRepository.findAllUserTestConnections(user.id); - const availableTestConnections = Constants.getTestConnectionsArr(); - if (allFoundUserTestConnections.length < availableTestConnections.length) { - const missingTestConnections = availableTestConnections.filter( - (testConnection) => - !allFoundUserTestConnections.some((foundConnection) => foundConnection.type === testConnection.type), - ); - const testConnectionsEntities = buildConnectionEntitiesFromTestDtos(missingTestConnections); - const createdTestConnections = await Promise.all( - testConnectionsEntities.map(async (connection): Promise => { - connection.author = user; - return await this._dbContext.connectionRepository.saveNewConnection(connection); - }), - ); - const testGroupsEntities = buildDefaultAdminGroups(user, createdTestConnections); - const createdTestGroups = await Promise.all( - testGroupsEntities.map(async (group: GroupEntity) => { - return await this._dbContext.groupRepository.saveNewOrUpdatedGroup(group); - }), - ); - const testPermissionsEntities = buildDefaultAdminPermissions(createdTestGroups); - await Promise.all( - testPermissionsEntities.map(async (permission: PermissionEntity) => { - await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(permission); - }), - ); - allFoundUserTestConnections.push(...createdTestConnections); - } - if (allFoundUserTestConnections.length > availableTestConnections.length) { - const testConnectionsToDelete = allFoundUserTestConnections.filter( - (foundConnection) => - !availableTestConnections.some((testConnection) => testConnection.type === foundConnection.type), - ); - await Promise.all( - testConnectionsToDelete.map(async (connection) => { - await this._dbContext.connectionRepository.remove(connection); - }), - ); - allFoundUserTestConnections = allFoundUserTestConnections.filter((foundConnection) => - availableTestConnections.some((testConnection) => testConnection.type === foundConnection.type), - ); - } - allFoundUserConnections.push(...allFoundUserTestConnections); - } + if (user.showTestConnections && isSaaS() && user.company.show_test_connections) { + let allFoundUserTestConnections = await this._dbContext.connectionRepository.findAllUserTestConnections(user.id); + const availableTestConnections = Constants.getTestConnectionsArr(); + if (allFoundUserTestConnections.length < availableTestConnections.length) { + const missingTestConnections = availableTestConnections.filter( + (testConnection) => + !allFoundUserTestConnections.some((foundConnection) => foundConnection.type === testConnection.type), + ); + const testConnectionsEntities = buildConnectionEntitiesFromTestDtos(missingTestConnections); + const createdTestConnections = await Promise.all( + testConnectionsEntities.map(async (connection): Promise => { + connection.author = user; + return await this._dbContext.connectionRepository.saveNewConnection(connection); + }), + ); + const testGroupsEntities = buildDefaultAdminGroups(user, createdTestConnections); + const createdTestGroups = await Promise.all( + testGroupsEntities.map(async (group: GroupEntity) => { + return await this._dbContext.groupRepository.saveNewOrUpdatedGroup(group); + }), + ); + const testPermissionsEntities = buildDefaultAdminPermissions(createdTestGroups); + await Promise.all( + testPermissionsEntities.map(async (permission: PermissionEntity) => { + await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(permission); + }), + ); + allFoundUserTestConnections.push(...createdTestConnections); + } + if (allFoundUserTestConnections.length > availableTestConnections.length) { + const testConnectionsToDelete = allFoundUserTestConnections.filter( + (foundConnection) => + !availableTestConnections.some((testConnection) => testConnection.type === foundConnection.type), + ); + await Promise.all( + testConnectionsToDelete.map(async (connection) => { + await this._dbContext.connectionRepository.remove(connection); + }), + ); + allFoundUserTestConnections = allFoundUserTestConnections.filter((foundConnection) => + availableTestConnections.some((testConnection) => testConnection.type === foundConnection.type), + ); + } + allFoundUserConnections.push(...allFoundUserTestConnections); + } - const filterConnectionKeys = (connection: ConnectionEntity, allowedKeys: Array): FilteredConnection => { - return Object.keys(connection).reduce((acc, key) => { - if (allowedKeys.includes(key)) { - // eslint-disable-next-line security/detect-object-injection - acc[key] = connection[key]; - } - return acc; - }, {} as FilteredConnection); - }; + const filterConnectionKeys = (connection: ConnectionEntity, allowedKeys: Array): FilteredConnection => { + return Object.keys(connection).reduce((acc, key) => { + if (allowedKeys.includes(key)) { + // eslint-disable-next-line security/detect-object-injection + acc[key] = connection[key]; + } + return acc; + }, {} as FilteredConnection); + }; - const connectionsWithPermissions = await Promise.all( - allFoundUserConnections.map(async (connection) => { - const accessLevel = await this._dbContext.userAccessRepository.getUserConnectionAccessLevel( - user.id, - connection.id, - ); - let filteredConnection: FilteredConnection = connection; + const connectionsWithPermissions = await Promise.all( + allFoundUserConnections.map(async (connection) => { + const accessLevel = await this._dbContext.userAccessRepository.getUserConnectionAccessLevel( + user.id, + connection.id, + ); + let filteredConnection: FilteredConnection = connection; - if (accessLevel === AccessLevelEnum.none) { - filteredConnection = filterConnectionKeys(connection, Constants.CONNECTION_KEYS_NONE_PERMISSION); - } else if (accessLevel !== AccessLevelEnum.edit) { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { signing_key, ...rest } = connection; - filteredConnection = rest; - } + if (accessLevel === AccessLevelEnum.none) { + filteredConnection = filterConnectionKeys(connection, Constants.CONNECTION_KEYS_NONE_PERMISSION); + } else if (accessLevel !== AccessLevelEnum.edit) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { signing_key, ...rest } = connection; + filteredConnection = rest; + } - return { - connection: buildFoundConnectionDs(filteredConnection), - accessLevel: accessLevel, - }; - }), - ); + return { + connection: buildFoundConnectionDs(filteredConnection), + accessLevel: accessLevel, + }; + }), + ); - await this.amplitudeService.formAndSendLogRecord(AmplitudeEventTypeEnum.connectionListReceived, user.id); - return { - connections: connectionsWithPermissions, - connectionsCount: connectionsWithPermissions.length, - }; - } + await this.amplitudeService.formAndSendLogRecord(AmplitudeEventTypeEnum.connectionListReceived, user.id); + return { + connections: connectionsWithPermissions, + connectionsCount: connectionsWithPermissions.length, + }; + } } diff --git a/backend/src/entities/connection/use-cases/find-all-users-in-connection.use.case.ts b/backend/src/entities/connection/use-cases/find-all-users-in-connection.use.case.ts index 78ae842fe..e257afe78 100644 --- a/backend/src/entities/connection/use-cases/find-all-users-in-connection.use.case.ts +++ b/backend/src/entities/connection/use-cases/find-all-users-in-connection.use.case.ts @@ -3,27 +3,27 @@ import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { FoundUserDto } from '../../user/dto/found-user.dto.js'; -import { IFindUsersInConnection } from './use-cases.interfaces.js'; -import { buildFoundUserDto } from '../../user/utils/build-found-user.dto.js'; import { UserEntity } from '../../user/user.entity.js'; +import { buildFoundUserDto } from '../../user/utils/build-found-user.dto.js'; +import { IFindUsersInConnection } from './use-cases.interfaces.js'; @Injectable() export class FindAllUsersInConnectionUseCase - extends AbstractUseCase> - implements IFindUsersInConnection + extends AbstractUseCase> + implements IFindUsersInConnection { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(connectionId: string): Promise> { - const userInConnection = await this._dbContext.userRepository.findAllUsersInConnection(connectionId); - return userInConnection.map((user) => { - //todo fix type after repository types are fixed - return buildFoundUserDto(user as UserEntity); - }); - } + protected async implementation(connectionId: string): Promise> { + const userInConnection = await this._dbContext.userRepository.findAllUsersInConnection(connectionId); + return userInConnection.map((user) => { + //todo fix type after repository types are fixed + return buildFoundUserDto(user as UserEntity); + }); + } } diff --git a/backend/src/entities/connection/use-cases/find-one-connection.use.case.ts b/backend/src/entities/connection/use-cases/find-one-connection.use.case.ts index b9b6b8cde..cee24c95d 100644 --- a/backend/src/entities/connection/use-cases/find-one-connection.use.case.ts +++ b/backend/src/entities/connection/use-cases/find-one-connection.use.case.ts @@ -10,121 +10,121 @@ import { Encryptor } from '../../../helpers/encryption/encryptor.js'; import { FoundConnectionPropertiesDs } from '../../connection-properties/application/data-structures/found-connection-properties.ds.js'; import { buildFoundConnectionPropertiesDs } from '../../connection-properties/utils/build-found-connection-properties-ds.js'; import { FindOneConnectionDs } from '../application/data-structures/find-one-connection.ds.js'; -import { IFindOneConnection } from './use-cases.interfaces.js'; import { FoundOneConnectionDs } from '../application/data-structures/found-one-connection.ds.js'; -import { buildFoundConnectionDs } from '../utils/build-found-connection.ds.js'; import { ConnectionEntity } from '../connection.entity.js'; +import { buildFoundConnectionDs } from '../utils/build-found-connection.ds.js'; import { FilteredConnection } from './find-all-connections.use.case.js'; +import { IFindOneConnection } from './use-cases.interfaces.js'; @Injectable() export class FindOneConnectionUseCase - extends AbstractUseCase - implements IFindOneConnection + extends AbstractUseCase + implements IFindOneConnection { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: FindOneConnectionDs): Promise { - const connection = await this._dbContext.connectionRepository.findOneConnection(inputData.connectionId); - if (!connection) { - throw new BadRequestException(Messages.CONNECTION_NOT_FOUND); - } - const accessLevel: AccessLevelEnum = await this._dbContext.userAccessRepository.getUserConnectionAccessLevel( - inputData.cognitoUserName, - inputData.connectionId, - ); + protected async implementation(inputData: FindOneConnectionDs): Promise { + const connection = await this._dbContext.connectionRepository.findOneConnection(inputData.connectionId); + if (!connection) { + throw new BadRequestException(Messages.CONNECTION_NOT_FOUND); + } + const accessLevel: AccessLevelEnum = await this._dbContext.userAccessRepository.getUserConnectionAccessLevel( + inputData.cognitoUserName, + inputData.connectionId, + ); - if (connection.masterEncryption && !inputData.masterPwd) { - throw new HttpException( - { - message: Messages.MASTER_PASSWORD_MISSING, - type: 'no_master_key', - }, - HttpStatus.BAD_REQUEST, - ); - } + if (connection.masterEncryption && !inputData.masterPwd) { + throw new HttpException( + { + message: Messages.MASTER_PASSWORD_MISSING, + type: 'no_master_key', + }, + HttpStatus.BAD_REQUEST, + ); + } - if (connection.masterEncryption && inputData.masterPwd) { - const isMaterPwdValid = await Encryptor.verifyUserPassword(inputData.masterPwd, connection.master_hash); - if (!isMaterPwdValid) { - throw new HttpException( - { - message: Messages.MASTER_PASSWORD_INCORRECT, - type: 'invalid_master_key', - }, - HttpStatus.BAD_REQUEST, - ); - } - } + if (connection.masterEncryption && inputData.masterPwd) { + const isMaterPwdValid = await Encryptor.verifyUserPassword(inputData.masterPwd, connection.master_hash); + if (!isMaterPwdValid) { + throw new HttpException( + { + message: Messages.MASTER_PASSWORD_INCORRECT, + type: 'invalid_master_key', + }, + HttpStatus.BAD_REQUEST, + ); + } + } - const filterConnectionKeys = (connection: ConnectionEntity, allowedKeys: Array): FilteredConnection => { - return Object.keys(connection).reduce((acc, key) => { - if (allowedKeys.includes(key)) { - // eslint-disable-next-line security/detect-object-injection - acc[key] = connection[key]; - } - return acc; - }, {} as FilteredConnection); - }; - let filteredConnection: FilteredConnection = connection; + const filterConnectionKeys = (connection: ConnectionEntity, allowedKeys: Array): FilteredConnection => { + return Object.keys(connection).reduce((acc, key) => { + if (allowedKeys.includes(key)) { + // eslint-disable-next-line security/detect-object-injection + acc[key] = connection[key]; + } + return acc; + }, {} as FilteredConnection); + }; + let filteredConnection: FilteredConnection = connection; - if (accessLevel === AccessLevelEnum.none) { - filteredConnection = filterConnectionKeys(connection, Constants.CONNECTION_KEYS_NONE_PERMISSION); - } else if (accessLevel !== AccessLevelEnum.edit) { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const { signing_key, ...rest } = connection; - filteredConnection = rest; - } + if (accessLevel === AccessLevelEnum.none) { + filteredConnection = filterConnectionKeys(connection, Constants.CONNECTION_KEYS_NONE_PERMISSION); + } else if (accessLevel !== AccessLevelEnum.edit) { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { signing_key, ...rest } = connection; + filteredConnection = rest; + } - if (filteredConnection.masterEncryption && inputData.masterPwd && accessLevel !== AccessLevelEnum.none) { - try { - filteredConnection = Encryptor.decryptConnectionCredentials(connection, inputData.masterPwd); - } catch (e) { - console.error('-> Error decrypting connection credentials', e); - throw new HttpException( - { - message: Messages.FAILED_DECRYPT_CONNECTION_CREDENTIALS, - }, - HttpStatus.INTERNAL_SERVER_ERROR, - ); - } - } + if (filteredConnection.masterEncryption && inputData.masterPwd && accessLevel !== AccessLevelEnum.none) { + try { + filteredConnection = Encryptor.decryptConnectionCredentials(connection, inputData.masterPwd); + } catch (e) { + console.error('-> Error decrypting connection credentials', e); + throw new HttpException( + { + message: Messages.FAILED_DECRYPT_CONNECTION_CREDENTIALS, + }, + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } - const groupManagement = await this.checkGroupManagement( - inputData.cognitoUserName, - inputData.connectionId, - accessLevel, - ); - const connectionProperties: FoundConnectionPropertiesDs = connection.connection_properties - ? buildFoundConnectionPropertiesDs(connection.connection_properties) - : null; - return { - connection: buildFoundConnectionDs(filteredConnection), - accessLevel: accessLevel, - groupManagement: groupManagement, - connectionProperties: connectionProperties, - }; - } + const groupManagement = await this.checkGroupManagement( + inputData.cognitoUserName, + inputData.connectionId, + accessLevel, + ); + const connectionProperties: FoundConnectionPropertiesDs = connection.connection_properties + ? buildFoundConnectionPropertiesDs(connection.connection_properties) + : null; + return { + connection: buildFoundConnectionDs(filteredConnection), + accessLevel: accessLevel, + groupManagement: groupManagement, + connectionProperties: connectionProperties, + }; + } - private async checkGroupManagement( - cognitoUserName: string, - connectionId: string, - availableConnectionAccessLevel = AccessLevelEnum.none, - ): Promise { - if (availableConnectionAccessLevel !== AccessLevelEnum.none) { - return true; - } - const groupsInConnection = await this._dbContext.groupRepository.findAllGroupsInConnection(connectionId); - for (const group of groupsInConnection) { - const groupRead = await this._dbContext.userAccessRepository.checkUserGroupRead(cognitoUserName, group.id); - if (groupRead) { - return true; - } - } - return false; - } + private async checkGroupManagement( + cognitoUserName: string, + connectionId: string, + availableConnectionAccessLevel = AccessLevelEnum.none, + ): Promise { + if (availableConnectionAccessLevel !== AccessLevelEnum.none) { + return true; + } + const groupsInConnection = await this._dbContext.groupRepository.findAllGroupsInConnection(connectionId); + for (const group of groupsInConnection) { + const groupRead = await this._dbContext.userAccessRepository.checkUserGroupRead(cognitoUserName, group.id); + if (groupRead) { + return true; + } + } + return false; + } } diff --git a/backend/src/entities/connection/use-cases/get-permissions-for-group-in-connection.use.case.ts b/backend/src/entities/connection/use-cases/get-permissions-for-group-in-connection.use.case.ts index 23b753051..a46b46bee 100644 --- a/backend/src/entities/connection/use-cases/get-permissions-for-group-in-connection.use.case.ts +++ b/backend/src/entities/connection/use-cases/get-permissions-for-group-in-connection.use.case.ts @@ -1,8 +1,8 @@ import { Inject, Injectable } from '@nestjs/common'; +import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import { TablePermissionDs } from '../../permission/application/data-structures/create-permissions.ds.js'; import { FoundPermissionsInConnectionDs } from '../application/data-structures/found-permissions-in-connection.ds.js'; import { GetPermissionsInConnectionDs } from '../application/data-structures/get-permissions-in-connection.ds.js'; @@ -10,62 +10,62 @@ import { IGetPermissionsForGroupInConnection } from './use-cases.interfaces.js'; @Injectable() export class GetPermissionsForGroupInConnectionUseCase - extends AbstractUseCase - implements IGetPermissionsForGroupInConnection + extends AbstractUseCase + implements IGetPermissionsForGroupInConnection { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: GetPermissionsInConnectionDs): Promise { - const groupPermissionForConnection = await this._dbContext.permissionRepository.getGroupPermissionForConnection( - inputData.connectionId, - inputData.groupId, - ); - const groupPermissionForGroup = await this._dbContext.permissionRepository.getGroupPermissionsForGroup( - inputData.connectionId, - inputData.groupId, - ); - const connection = await this._dbContext.connectionRepository.findAndDecryptConnection( - inputData.connectionId, - inputData.masterPwd, - ); - const dao = getDataAccessObject(connection); - const tables: Array = (await dao.getTablesFromDB()).map((table) => table.tableName); + protected async implementation(inputData: GetPermissionsInConnectionDs): Promise { + const groupPermissionForConnection = await this._dbContext.permissionRepository.getGroupPermissionForConnection( + inputData.connectionId, + inputData.groupId, + ); + const groupPermissionForGroup = await this._dbContext.permissionRepository.getGroupPermissionsForGroup( + inputData.connectionId, + inputData.groupId, + ); + const connection = await this._dbContext.connectionRepository.findAndDecryptConnection( + inputData.connectionId, + inputData.masterPwd, + ); + const dao = getDataAccessObject(connection); + const tables: Array = (await dao.getTablesFromDB()).map((table) => table.tableName); - const tablesWithAccessLevels: Array = await Promise.all( - tables.map(async (table: string) => { - return await this._dbContext.permissionRepository.getGroupPermissionsForTable( - inputData.connectionId, - inputData.groupId, - table, - ); - }), - ); - const allTableSettingsInConnection = await this._dbContext.tableSettingsRepository.findTableSettingsInConnection( - inputData.connectionId, - ); - return { - connection: { - connectionId: inputData.connectionId, - accessLevel: groupPermissionForConnection, - }, - group: { - groupId: inputData.groupId, - accessLevel: groupPermissionForGroup, - }, - tables: tablesWithAccessLevels.map((table) => { - const tableSettings = allTableSettingsInConnection.find( - (tableSettings) => tableSettings.table_name === table.tableName, - ); - return { - ...table, - display_name: tableSettings?.display_name ?? null, - }; - }), - }; - } + const tablesWithAccessLevels: Array = await Promise.all( + tables.map(async (table: string) => { + return await this._dbContext.permissionRepository.getGroupPermissionsForTable( + inputData.connectionId, + inputData.groupId, + table, + ); + }), + ); + const allTableSettingsInConnection = await this._dbContext.tableSettingsRepository.findTableSettingsInConnection( + inputData.connectionId, + ); + return { + connection: { + connectionId: inputData.connectionId, + accessLevel: groupPermissionForConnection, + }, + group: { + groupId: inputData.groupId, + accessLevel: groupPermissionForGroup, + }, + tables: tablesWithAccessLevels.map((table) => { + const tableSettings = allTableSettingsInConnection.find( + (tableSettings) => tableSettings.table_name === table.tableName, + ); + return { + ...table, + display_name: tableSettings?.display_name ?? null, + }; + }), + }; + } } diff --git a/backend/src/entities/connection/use-cases/get-user-groups-in-connection.use.case.ts b/backend/src/entities/connection/use-cases/get-user-groups-in-connection.use.case.ts index b829499f0..be076cd20 100644 --- a/backend/src/entities/connection/use-cases/get-user-groups-in-connection.use.case.ts +++ b/backend/src/entities/connection/use-cases/get-user-groups-in-connection.use.case.ts @@ -4,35 +4,35 @@ import { IGlobalDatabaseContext } from '../../../common/application/global-datab import { BaseType } from '../../../common/data-injection.tokens.js'; import { GroupEntity } from '../../group/group.entity.js'; import { GetGroupsInConnectionDs } from '../application/data-structures/get-groups-in-connection.ds.js'; -import { IGetUserGroupsInConnection } from './use-cases.interfaces.js'; import { FoundUserGroupsInConnectionDTO } from '../application/dto/found-user-groups-in-connection.dto.js'; import { buildFoundUserGroupInConnectionDto } from '../utils/build-found-user-group-in-connection-dto.util.js'; +import { IGetUserGroupsInConnection } from './use-cases.interfaces.js'; @Injectable() export class GetUserGroupsInConnectionUseCase - extends AbstractUseCase> - implements IGetUserGroupsInConnection + extends AbstractUseCase> + implements IGetUserGroupsInConnection { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: GetGroupsInConnectionDs): Promise> { - const userGroups = await this._dbContext.groupRepository.findAllUserGroupsInConnection( - inputData.connectionId, - inputData.cognitoUserName, - ); - return await Promise.all( - userGroups.map(async (group: GroupEntity) => { - const userAccessLevel = await this._dbContext.userAccessRepository.getGroupAccessLevel( - inputData.cognitoUserName, - group.id, - ); - return buildFoundUserGroupInConnectionDto(group, userAccessLevel); - }), - ); - } + protected async implementation(inputData: GetGroupsInConnectionDs): Promise> { + const userGroups = await this._dbContext.groupRepository.findAllUserGroupsInConnection( + inputData.connectionId, + inputData.cognitoUserName, + ); + return await Promise.all( + userGroups.map(async (group: GroupEntity) => { + const userAccessLevel = await this._dbContext.userAccessRepository.getGroupAccessLevel( + inputData.cognitoUserName, + group.id, + ); + return buildFoundUserGroupInConnectionDto(group, userAccessLevel); + }), + ); + } } diff --git a/backend/src/entities/connection/use-cases/get-user-permissions-for-group-in-connection.use.case.ts b/backend/src/entities/connection/use-cases/get-user-permissions-for-group-in-connection.use.case.ts index 24d4fd695..286c5ddd5 100644 --- a/backend/src/entities/connection/use-cases/get-user-permissions-for-group-in-connection.use.case.ts +++ b/backend/src/entities/connection/use-cases/get-user-permissions-for-group-in-connection.use.case.ts @@ -1,8 +1,8 @@ import { Inject, Injectable } from '@nestjs/common'; +import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import { TablePermissionDs } from '../../permission/application/data-structures/create-permissions.ds.js'; import { FoundPermissionsInConnectionDs } from '../application/data-structures/found-permissions-in-connection.ds.js'; import { GetPermissionsInConnectionDs } from '../application/data-structures/get-permissions-in-connection.ds.js'; @@ -10,61 +10,61 @@ import { IGetPermissionsForGroupInConnection } from './use-cases.interfaces.js'; @Injectable() export class GetUserPermissionsForGroupInConnectionUseCase - extends AbstractUseCase - implements IGetPermissionsForGroupInConnection + extends AbstractUseCase + implements IGetPermissionsForGroupInConnection { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: GetPermissionsInConnectionDs): Promise { - const { connectionId, groupId, cognitoUserName, masterPwd } = inputData; - const userConnectionAccessLevel = await this._dbContext.userAccessRepository.getUserConnectionAccessLevel( - cognitoUserName, - connectionId, - ); - const userGroupAccessLevel = await this._dbContext.userAccessRepository.getGroupAccessLevel( - cognitoUserName, - groupId, - ); + protected async implementation(inputData: GetPermissionsInConnectionDs): Promise { + const { connectionId, groupId, cognitoUserName, masterPwd } = inputData; + const userConnectionAccessLevel = await this._dbContext.userAccessRepository.getUserConnectionAccessLevel( + cognitoUserName, + connectionId, + ); + const userGroupAccessLevel = await this._dbContext.userAccessRepository.getGroupAccessLevel( + cognitoUserName, + groupId, + ); - const connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, masterPwd); - const dao = getDataAccessObject(connection); - const tables: Array = (await dao.getTablesFromDB()).map((table) => table.tableName); - const tablesWithAccessLevels: Array = await Promise.all( - tables.map(async (table) => { - return await this._dbContext.userAccessRepository.getUserTablePermissions( - cognitoUserName, - connectionId, - table, - masterPwd, - ); - }), - ); - const allTableSettingsInConnection = await this._dbContext.tableSettingsRepository.findTableSettingsInConnection( - inputData.connectionId, - ); - return { - connection: { - connectionId: connectionId, - accessLevel: userConnectionAccessLevel, - }, - group: { - groupId: groupId, - accessLevel: userGroupAccessLevel, - }, - tables: tablesWithAccessLevels.map((table) => { - const tableSettings = allTableSettingsInConnection.find( - (tableSettings) => tableSettings.table_name === table.tableName, - ); - return { - ...table, - display_name: tableSettings?.display_name ?? null, - }; - }), - }; - } + const connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, masterPwd); + const dao = getDataAccessObject(connection); + const tables: Array = (await dao.getTablesFromDB()).map((table) => table.tableName); + const tablesWithAccessLevels: Array = await Promise.all( + tables.map(async (table) => { + return await this._dbContext.userAccessRepository.getUserTablePermissions( + cognitoUserName, + connectionId, + table, + masterPwd, + ); + }), + ); + const allTableSettingsInConnection = await this._dbContext.tableSettingsRepository.findTableSettingsInConnection( + inputData.connectionId, + ); + return { + connection: { + connectionId: connectionId, + accessLevel: userConnectionAccessLevel, + }, + group: { + groupId: groupId, + accessLevel: userGroupAccessLevel, + }, + tables: tablesWithAccessLevels.map((table) => { + const tableSettings = allTableSettingsInConnection.find( + (tableSettings) => tableSettings.table_name === table.tableName, + ); + return { + ...table, + display_name: tableSettings?.display_name ?? null, + }; + }), + }; + } } diff --git a/backend/src/entities/connection/use-cases/refresh-connection-agent-token.use.case.ts b/backend/src/entities/connection/use-cases/refresh-connection-agent-token.use.case.ts index 1280b0db3..2ff242f63 100644 --- a/backend/src/entities/connection/use-cases/refresh-connection-agent-token.use.case.ts +++ b/backend/src/entities/connection/use-cases/refresh-connection-agent-token.use.case.ts @@ -7,20 +7,20 @@ import { IRefreshConnectionAgentToken } from './use-cases.interfaces.js'; @Injectable() export class RefreshConnectionAgentTokenUseCase - extends AbstractUseCase - implements IRefreshConnectionAgentToken + extends AbstractUseCase + implements IRefreshConnectionAgentToken { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(connectionId: string): Promise { - const refreshedToken = await this._dbContext.agentRepository.renewOrCreateConnectionToken(connectionId); - return { - token: refreshedToken, - }; - } + protected async implementation(connectionId: string): Promise { + const refreshedToken = await this._dbContext.agentRepository.renewOrCreateConnectionToken(connectionId); + return { + token: refreshedToken, + }; + } } diff --git a/backend/src/entities/connection/use-cases/restore-connection-use.case.ts b/backend/src/entities/connection/use-cases/restore-connection-use.case.ts index 2e0ca2f9a..cc4fab3c3 100644 --- a/backend/src/entities/connection/use-cases/restore-connection-use.case.ts +++ b/backend/src/entities/connection/use-cases/restore-connection-use.case.ts @@ -15,67 +15,67 @@ import { IRestoreConnection } from './use-cases.interfaces.js'; @Injectable() export class RestoreConnectionUseCase - extends AbstractUseCase - implements IRestoreConnection + extends AbstractUseCase + implements IRestoreConnection { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - // private readonly saasCompanyGatewayService: SaasCompanyGatewayService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + // private readonly saasCompanyGatewayService: SaasCompanyGatewayService, + ) { + super(); + } - protected async implementation(connectionData: UpdateConnectionDs): Promise { - const { - connection_parameters, - update_info: { connectionId }, - } = connectionData; + protected async implementation(connectionData: UpdateConnectionDs): Promise { + const { + connection_parameters, + update_info: { connectionId }, + } = connectionData; - if (connection_parameters.masterEncryption && !connectionData.update_info.masterPwd) { - throw new HttpException( - { - message: Messages.MASTER_PASSWORD_REQUIRED, - }, - HttpStatus.BAD_REQUEST, - ); - } + if (connection_parameters.masterEncryption && !connectionData.update_info.masterPwd) { + throw new HttpException( + { + message: Messages.MASTER_PASSWORD_REQUIRED, + }, + HttpStatus.BAD_REQUEST, + ); + } - const foundConnection = await this._dbContext.connectionRepository.findOneById(connectionId); - if (!foundConnection) { - throw new HttpException( - { - message: Messages.CONNECTION_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - const hostCheckingResult = await isHostAllowed(connection_parameters); - if (!hostCheckingResult) { - throw new HttpException( - { - message: Messages.CANNOT_CREATE_CONNECTION_TO_THIS_HOST, - }, - HttpStatus.FORBIDDEN, - ); - } + const foundConnection = await this._dbContext.connectionRepository.findOneById(connectionId); + if (!foundConnection) { + throw new HttpException( + { + message: Messages.CONNECTION_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + const hostCheckingResult = await isHostAllowed(connection_parameters); + if (!hostCheckingResult) { + throw new HttpException( + { + message: Messages.CANNOT_CREATE_CONNECTION_TO_THIS_HOST, + }, + HttpStatus.FORBIDDEN, + ); + } - const isTestConnection = isHostTest(connectionData.connection_parameters.host); - const updatedConnection = await updateConnectionEntityForRestoration( - foundConnection, - connectionData, - isTestConnection, - ); - if (isConnectionEntityAgent(updatedConnection)) { - updatedConnection.agent = await this._dbContext.agentRepository.createNewAgentForConnection(updatedConnection); - } - const savedConnection = await this._dbContext.connectionRepository.save(updatedConnection); - const foundConnectionAfterSave = await this._dbContext.connectionRepository.findOne({ - where: { id: savedConnection.id }, - }); - const token = updatedConnection.agent?.token || null; - return { - connection: buildCreatedConnectionDs(foundConnectionAfterSave, token, connectionData.update_info.masterPwd), - }; - } + const isTestConnection = isHostTest(connectionData.connection_parameters.host); + const updatedConnection = await updateConnectionEntityForRestoration( + foundConnection, + connectionData, + isTestConnection, + ); + if (isConnectionEntityAgent(updatedConnection)) { + updatedConnection.agent = await this._dbContext.agentRepository.createNewAgentForConnection(updatedConnection); + } + const savedConnection = await this._dbContext.connectionRepository.save(updatedConnection); + const foundConnectionAfterSave = await this._dbContext.connectionRepository.findOne({ + where: { id: savedConnection.id }, + }); + const token = updatedConnection.agent?.token || null; + return { + connection: buildCreatedConnectionDs(foundConnectionAfterSave, token, connectionData.update_info.masterPwd), + }; + } } diff --git a/backend/src/entities/connection/use-cases/test-connection.use.case.ts b/backend/src/entities/connection/use-cases/test-connection.use.case.ts index a62143108..26109543a 100644 --- a/backend/src/entities/connection/use-cases/test-connection.use.case.ts +++ b/backend/src/entities/connection/use-cases/test-connection.use.case.ts @@ -1,7 +1,7 @@ import { Inject, Injectable } from '@nestjs/common'; import { - getDataAccessObject, - isRedisConnectionUrl, + getDataAccessObject, + isRedisConnectionUrl, } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; import { getRepository } from 'typeorm'; @@ -22,174 +22,174 @@ import { ITestConnection } from './use-cases.interfaces.js'; @Injectable() export class TestConnectionUseCase - extends AbstractUseCase - implements ITestConnection + extends AbstractUseCase + implements ITestConnection { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } - - protected async implementation(inputData: UpdateConnectionDs): Promise { - const checkingResult = await isHostAllowed(inputData.connection_parameters); - if (!checkingResult) { - return { - result: false, - message: Messages.CANNOT_CREATE_CONNECTION_TO_THIS_HOST, - }; - } - - let { - // eslint-disable-next-line prefer-const - update_info: { connectionId, masterPwd }, - connection_parameters: connectionData, - } = inputData; - - if (connectionId) { - try { - let toUpdate = await this._dbContext.connectionRepository.findOne({ where: { id: connectionId } }); - if (!toUpdate) { - return { - result: false, - message: Messages.CONNECTION_NOT_FOUND, - }; - } - if (toUpdate?.masterEncryption && !masterPwd) { - return { - result: false, - message: Messages.MASTER_PASSWORD_MISSING, - }; - } - if (isConnectionTypeAgent(toUpdate.type)) { - const qb = await getRepository(ConnectionEntity) - .createQueryBuilder('connection') - .leftJoinAndSelect('connection.agent', 'agent') - .where('connection.id = :id', { id: connectionId }); - toUpdate = await qb.getOne(); - } - - if (!toUpdate) { - return { - result: false, - message: Messages.CONNECTION_NOT_FOUND, - }; - } - - ['password', 'privateSSHKey', 'cert'].forEach((key) => { - // eslint-disable-next-line security/detect-object-injection - if (!connectionData[key]) { - // eslint-disable-next-line security/detect-object-injection - delete connectionData[key]; - } - }); - - if (toUpdate.masterEncryption && (!masterPwd || masterPwd.length <= 0)) { - return { - result: false, - message: Messages.MASTER_PASSWORD_MISSING, - }; - } - - if (toUpdate.masterEncryption) { - toUpdate = Encryptor.decryptConnectionCredentials(toUpdate, masterPwd); - } - - if ( - !connectionData.password && - (connectionData.host !== toUpdate.host || connectionData.port !== toUpdate.port) && - !isConnectionTypeAgent(connectionData.type) && - !isRedisConnectionUrl(connectionData.host) - ) { - return { - result: false, - message: Messages.PASSWORD_MISSING, - }; - } - - let updated: any = Object.assign(toUpdate, connectionData); - const dataForProcessing: CreateConnectionDs = { - connection_parameters: updated, - creation_info: null, - }; - updated = (await processAWSConnection(dataForProcessing)).connection_parameters; - const dao = getDataAccessObject(updated); - - return await this.testConnection( - dao, - updated, - inputData.update_info.authorId, - inputData.connection_parameters.type, - ); - } catch (e) { - return { - result: false, - message: `${Messages.CONNECTION_TEST_FILED}${e ? e : ''}`, - }; - } - } else { - if ( - !connectionData.password && - !isConnectionTypeAgent(connectionData.type) && - !isRedisConnectionUrl(connectionData.host) - ) { - return { - result: false, - message: Messages.PASSWORD_MISSING, - }; - } - - const dataForProcessing: CreateConnectionDs = { - connection_parameters: connectionData, - creation_info: null, - }; - connectionData = (await processAWSConnection(dataForProcessing)).connection_parameters; - const dao = getDataAccessObject(connectionData as ConnectionEntity); - - return await this.testConnection( - dao, - connectionData, - inputData.update_info.authorId, - inputData.connection_parameters.type, - ); - } - } - - private async testConnection( - dao: any, - connectionData: any, - authorId: string, - connectionType: ConnectionTypesEnum, - ): Promise { - let testResult: TestConnectionResultDs; - try { - testResult = await dao.testConnect(); - return testResult; - } catch (e) { - let text: string = e.message.toLowerCase(); - - if (text.includes('ssl required') || text.includes('ssl connection required')) { - connectionData.ssl = true; - const dao = getDataAccessObject(connectionData); - try { - testResult = await dao.testConnect(); - return testResult; - } catch (e) { - text = e.message; - } - } - - text = processExceptionMessage(text); - return { - result: false, - message: text, - }; - } finally { - if (testResult?.result) { - const foundUser = await this._dbContext.userRepository.findOneUserById(authorId); - await slackPostMessage(Messages.USER_SUCCESSFULLY_TESTED_CONNECTION(foundUser?.email, connectionType)); - } - } - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } + + protected async implementation(inputData: UpdateConnectionDs): Promise { + const checkingResult = await isHostAllowed(inputData.connection_parameters); + if (!checkingResult) { + return { + result: false, + message: Messages.CANNOT_CREATE_CONNECTION_TO_THIS_HOST, + }; + } + + let { + // eslint-disable-next-line prefer-const + update_info: { connectionId, masterPwd }, + connection_parameters: connectionData, + } = inputData; + + if (connectionId) { + try { + let toUpdate = await this._dbContext.connectionRepository.findOne({ where: { id: connectionId } }); + if (!toUpdate) { + return { + result: false, + message: Messages.CONNECTION_NOT_FOUND, + }; + } + if (toUpdate?.masterEncryption && !masterPwd) { + return { + result: false, + message: Messages.MASTER_PASSWORD_MISSING, + }; + } + if (isConnectionTypeAgent(toUpdate.type)) { + const qb = await getRepository(ConnectionEntity) + .createQueryBuilder('connection') + .leftJoinAndSelect('connection.agent', 'agent') + .where('connection.id = :id', { id: connectionId }); + toUpdate = await qb.getOne(); + } + + if (!toUpdate) { + return { + result: false, + message: Messages.CONNECTION_NOT_FOUND, + }; + } + + ['password', 'privateSSHKey', 'cert'].forEach((key) => { + // eslint-disable-next-line security/detect-object-injection + if (!connectionData[key]) { + // eslint-disable-next-line security/detect-object-injection + delete connectionData[key]; + } + }); + + if (toUpdate.masterEncryption && (!masterPwd || masterPwd.length <= 0)) { + return { + result: false, + message: Messages.MASTER_PASSWORD_MISSING, + }; + } + + if (toUpdate.masterEncryption) { + toUpdate = Encryptor.decryptConnectionCredentials(toUpdate, masterPwd); + } + + if ( + !connectionData.password && + (connectionData.host !== toUpdate.host || connectionData.port !== toUpdate.port) && + !isConnectionTypeAgent(connectionData.type) && + !isRedisConnectionUrl(connectionData.host) + ) { + return { + result: false, + message: Messages.PASSWORD_MISSING, + }; + } + + let updated: any = Object.assign(toUpdate, connectionData); + const dataForProcessing: CreateConnectionDs = { + connection_parameters: updated, + creation_info: null, + }; + updated = (await processAWSConnection(dataForProcessing)).connection_parameters; + const dao = getDataAccessObject(updated); + + return await this.testConnection( + dao, + updated, + inputData.update_info.authorId, + inputData.connection_parameters.type, + ); + } catch (e) { + return { + result: false, + message: `${Messages.CONNECTION_TEST_FILED}${e ? e : ''}`, + }; + } + } else { + if ( + !connectionData.password && + !isConnectionTypeAgent(connectionData.type) && + !isRedisConnectionUrl(connectionData.host) + ) { + return { + result: false, + message: Messages.PASSWORD_MISSING, + }; + } + + const dataForProcessing: CreateConnectionDs = { + connection_parameters: connectionData, + creation_info: null, + }; + connectionData = (await processAWSConnection(dataForProcessing)).connection_parameters; + const dao = getDataAccessObject(connectionData as ConnectionEntity); + + return await this.testConnection( + dao, + connectionData, + inputData.update_info.authorId, + inputData.connection_parameters.type, + ); + } + } + + private async testConnection( + dao: any, + connectionData: any, + authorId: string, + connectionType: ConnectionTypesEnum, + ): Promise { + let testResult: TestConnectionResultDs; + try { + testResult = await dao.testConnect(); + return testResult; + } catch (e) { + let text: string = e.message.toLowerCase(); + + if (text.includes('ssl required') || text.includes('ssl connection required')) { + connectionData.ssl = true; + const dao = getDataAccessObject(connectionData); + try { + testResult = await dao.testConnect(); + return testResult; + } catch (e) { + text = e.message; + } + } + + text = processExceptionMessage(text); + return { + result: false, + message: text, + }; + } finally { + if (testResult?.result) { + const foundUser = await this._dbContext.userRepository.findOneUserById(authorId); + await slackPostMessage(Messages.USER_SUCCESSFULLY_TESTED_CONNECTION(foundUser?.email, connectionType)); + } + } + } } diff --git a/backend/src/entities/connection/use-cases/unfreeze-connection.use.case.ts b/backend/src/entities/connection/use-cases/unfreeze-connection.use.case.ts index 8fe022a9c..d0ea827bf 100644 --- a/backend/src/entities/connection/use-cases/unfreeze-connection.use.case.ts +++ b/backend/src/entities/connection/use-cases/unfreeze-connection.use.case.ts @@ -8,36 +8,36 @@ import { IUnfreezeConnection } from './use-cases.interfaces.js'; @Injectable({ scope: Scope.REQUEST }) export class UnfreezeConnectionUseCase - extends AbstractUseCase - implements IUnfreezeConnection + extends AbstractUseCase + implements IUnfreezeConnection { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - // private readonly saasCompanyGatewayService: SaasCompanyGatewayService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + // private readonly saasCompanyGatewayService: SaasCompanyGatewayService, + ) { + super(); + } - protected async implementation(inputData: UnfreezeConnectionDs): Promise { - const { connectionId } = inputData; + protected async implementation(inputData: UnfreezeConnectionDs): Promise { + const { connectionId } = inputData; - const connection = await this._dbContext.connectionRepository.findOne({ where: { id: connectionId } }); + const connection = await this._dbContext.connectionRepository.findOne({ where: { id: connectionId } }); - // if (isSaaS()) { - // const userCompany = await this._dbContext.companyInfoRepository.finOneCompanyInfoByUserId(userId); - // const companyInfoFromSaas = await this.saasCompanyGatewayService.getCompanyInfo(userCompany.id); - // if (companyInfoFromSaas.subscriptionLevel === SubscriptionLevelEnum.FREE_PLAN) { - // if (Constants.NON_FREE_PLAN_CONNECTION_TYPES.includes(connection.type as ConnectionTypesEnum)) { - // throw new NonAvailableInFreePlanException( - // Messages.CANNOT_CREATE_CONNECTION_THIS_TYPE_IN_FREE_PLAN(connection.type as ConnectionTypesEnum), - // ); - // } - // } - // } + // if (isSaaS()) { + // const userCompany = await this._dbContext.companyInfoRepository.finOneCompanyInfoByUserId(userId); + // const companyInfoFromSaas = await this.saasCompanyGatewayService.getCompanyInfo(userCompany.id); + // if (companyInfoFromSaas.subscriptionLevel === SubscriptionLevelEnum.FREE_PLAN) { + // if (Constants.NON_FREE_PLAN_CONNECTION_TYPES.includes(connection.type as ConnectionTypesEnum)) { + // throw new NonAvailableInFreePlanException( + // Messages.CANNOT_CREATE_CONNECTION_THIS_TYPE_IN_FREE_PLAN(connection.type as ConnectionTypesEnum), + // ); + // } + // } + // } - connection.is_frozen = false; - await this._dbContext.connectionRepository.save(connection); - return { success: true }; - } + connection.is_frozen = false; + await this._dbContext.connectionRepository.save(connection); + return { success: true }; + } } diff --git a/backend/src/entities/connection/use-cases/update-connection-master-password.use.case.ts b/backend/src/entities/connection/use-cases/update-connection-master-password.use.case.ts index 59722ae13..91d72fb50 100644 --- a/backend/src/entities/connection/use-cases/update-connection-master-password.use.case.ts +++ b/backend/src/entities/connection/use-cases/update-connection-master-password.use.case.ts @@ -3,28 +3,28 @@ import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Encryptor } from '../../../helpers/encryption/encryptor.js'; +import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; import { UpdateMasterPasswordDs } from '../application/data-structures/update-master-password.ds.js'; import { IUpdateMasterPassword } from './use-cases.interfaces.js'; -import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; @Injectable() export class UpdateConnectionMasterPasswordUseCase - extends AbstractUseCase - implements IUpdateMasterPassword + extends AbstractUseCase + implements IUpdateMasterPassword { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: UpdateMasterPasswordDs): Promise { - const { connectionId, newMasterPwd, oldMasterPwd } = inputData; - let connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, oldMasterPwd); - connection = Encryptor.encryptConnectionCredentials(connection, newMasterPwd); - connection.master_hash = await Encryptor.hashUserPassword(newMasterPwd); - const updatedConnection = await this._dbContext.connectionRepository.saveNewConnection(connection); - return { success: !!updatedConnection }; - } + protected async implementation(inputData: UpdateMasterPasswordDs): Promise { + const { connectionId, newMasterPwd, oldMasterPwd } = inputData; + let connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, oldMasterPwd); + connection = Encryptor.encryptConnectionCredentials(connection, newMasterPwd); + connection.master_hash = await Encryptor.hashUserPassword(newMasterPwd); + const updatedConnection = await this._dbContext.connectionRepository.saveNewConnection(connection); + return { success: !!updatedConnection }; + } } diff --git a/backend/src/entities/connection/use-cases/update-connection.use.case.ts b/backend/src/entities/connection/use-cases/update-connection.use.case.ts index 5dfa9d07c..7f6723f46 100644 --- a/backend/src/entities/connection/use-cases/update-connection.use.case.ts +++ b/backend/src/entities/connection/use-cases/update-connection.use.case.ts @@ -20,140 +20,140 @@ import { IUpdateConnection } from './use-cases.interfaces.js'; @Injectable() export class UpdateConnectionUseCase - extends AbstractUseCase> - implements IUpdateConnection + extends AbstractUseCase> + implements IUpdateConnection { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private readonly amplitudeService: AmplitudeService, - // private readonly saasCompanyGatewayService: SaasCompanyGatewayService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly amplitudeService: AmplitudeService, + // private readonly saasCompanyGatewayService: SaasCompanyGatewayService, + ) { + super(); + } - protected async implementation( - updateConnectionData: UpdateConnectionDs, - ): Promise> { - const { - update_info: { masterPwd, connectionId, authorId }, - } = updateConnectionData; - let { connection_parameters } = updateConnectionData; - await validateCreateConnectionData(updateConnectionData); + protected async implementation( + updateConnectionData: UpdateConnectionDs, + ): Promise> { + const { + update_info: { masterPwd, connectionId, authorId }, + } = updateConnectionData; + let { connection_parameters } = updateConnectionData; + await validateCreateConnectionData(updateConnectionData); - // if (isSaaS()) { - // const userCompany = await this._dbContext.companyInfoRepository.finOneCompanyInfoByUserId(authorId); - // const companyInfoFromSaas = await this.saasCompanyGatewayService.getCompanyInfo(userCompany.id); - // if (companyInfoFromSaas.subscriptionLevel === SubscriptionLevelEnum.FREE_PLAN) { - // if (Constants.NON_FREE_PLAN_CONNECTION_TYPES.includes(updateConnectionData.connection_parameters.type)) { - // throw new NonAvailableInFreePlanException( - // Messages.CANNOT_CREATE_CONNECTION_THIS_TYPE_IN_FREE_PLAN(updateConnectionData.connection_parameters.type), - // ); - // } - // } - // } + // if (isSaaS()) { + // const userCompany = await this._dbContext.companyInfoRepository.finOneCompanyInfoByUserId(authorId); + // const companyInfoFromSaas = await this.saasCompanyGatewayService.getCompanyInfo(userCompany.id); + // if (companyInfoFromSaas.subscriptionLevel === SubscriptionLevelEnum.FREE_PLAN) { + // if (Constants.NON_FREE_PLAN_CONNECTION_TYPES.includes(updateConnectionData.connection_parameters.type)) { + // throw new NonAvailableInFreePlanException( + // Messages.CANNOT_CREATE_CONNECTION_THIS_TYPE_IN_FREE_PLAN(updateConnectionData.connection_parameters.type), + // ); + // } + // } + // } - const foundConnectionToUpdate = await this._dbContext.connectionRepository.findAndDecryptConnection( - connectionId, - masterPwd, - ); - const testConnectionsHosts = Constants.getTestConnectionsHostNamesArr(); + const foundConnectionToUpdate = await this._dbContext.connectionRepository.findAndDecryptConnection( + connectionId, + masterPwd, + ); + const testConnectionsHosts = Constants.getTestConnectionsHostNamesArr(); - if (testConnectionsHosts.includes(foundConnectionToUpdate.host)) { - throw new HttpException( - { - message: Messages.TEST_CONNECTIONS_UPDATE_NOT_ALLOWED, - }, - HttpStatus.BAD_REQUEST, - ); - } + if (testConnectionsHosts.includes(foundConnectionToUpdate.host)) { + throw new HttpException( + { + message: Messages.TEST_CONNECTIONS_UPDATE_NOT_ALLOWED, + }, + HttpStatus.BAD_REQUEST, + ); + } - this.checkPasswordRequired(foundConnectionToUpdate, updateConnectionData.connection_parameters); + this.checkPasswordRequired(foundConnectionToUpdate, updateConnectionData.connection_parameters); - const booleanKeys = Object.entries(connection_parameters) - .filter(([_, value]) => typeof value === 'boolean') - .map(([key, _]) => key); + const booleanKeys = Object.entries(connection_parameters) + .filter(([_, value]) => typeof value === 'boolean') + .map(([key, _]) => key); - const keysToKeep = ['title', 'schema', ...booleanKeys]; - connection_parameters = Object.keys(connection_parameters).reduce( - (acc, key) => { - // eslint-disable-next-line security/detect-object-injection - if (connection_parameters[key] || keysToKeep.includes(key)) { - // eslint-disable-next-line security/detect-object-injection - acc[key] = connection_parameters[key]; - } - return acc; - }, - {} as UpdateConnectionDs['connection_parameters'], - ); + const keysToKeep = ['title', 'schema', ...booleanKeys]; + connection_parameters = Object.keys(connection_parameters).reduce( + (acc, key) => { + // eslint-disable-next-line security/detect-object-injection + if (connection_parameters[key] || keysToKeep.includes(key)) { + // eslint-disable-next-line security/detect-object-injection + acc[key] = connection_parameters[key]; + } + return acc; + }, + {} as UpdateConnectionDs['connection_parameters'], + ); - let updatedConnection: ConnectionEntity = Object.assign(foundConnectionToUpdate, connection_parameters); - let connectionToken = null; - if (isConnectionTypeAgent(updatedConnection.type)) { - connectionToken = await this.renewOrCreateConnectionToken(updatedConnection.id); - updatedConnection = this.clearNonRequiredConnectionAgentProperties(updatedConnection); - } - if (updatedConnection.masterEncryption && masterPwd) { - updatedConnection = Encryptor.encryptConnectionCredentials(updatedConnection, masterPwd); - updatedConnection.master_hash = await Encryptor.hashUserPassword(masterPwd); - } - const savedConnection = await this._dbContext.connectionRepository.saveNewConnection(updatedConnection); - const isTestConnection = isTestConnectionUtil(savedConnection); - await this.amplitudeService.formAndSendLogRecord( - isTestConnection ? AmplitudeEventTypeEnum.connectionUpdatedTest : AmplitudeEventTypeEnum.connectionUpdated, - authorId, - ); - return buildCreatedConnectionDs(savedConnection, connectionToken, masterPwd); - } + let updatedConnection: ConnectionEntity = Object.assign(foundConnectionToUpdate, connection_parameters); + let connectionToken = null; + if (isConnectionTypeAgent(updatedConnection.type)) { + connectionToken = await this.renewOrCreateConnectionToken(updatedConnection.id); + updatedConnection = this.clearNonRequiredConnectionAgentProperties(updatedConnection); + } + if (updatedConnection.masterEncryption && masterPwd) { + updatedConnection = Encryptor.encryptConnectionCredentials(updatedConnection, masterPwd); + updatedConnection.master_hash = await Encryptor.hashUserPassword(masterPwd); + } + const savedConnection = await this._dbContext.connectionRepository.saveNewConnection(updatedConnection); + const isTestConnection = isTestConnectionUtil(savedConnection); + await this.amplitudeService.formAndSendLogRecord( + isTestConnection ? AmplitudeEventTypeEnum.connectionUpdatedTest : AmplitudeEventTypeEnum.connectionUpdated, + authorId, + ); + return buildCreatedConnectionDs(savedConnection, connectionToken, masterPwd); + } - private checkPasswordRequired( - foundConnectionToUpdate: ConnectionEntity, - newConnectionParameters: UpdateConnectionDs['connection_parameters'], - ): void { - if (this.isPasswordUpdateRequired(newConnectionParameters, foundConnectionToUpdate)) { - throw new HttpException( - { - message: Messages.PASSWORD_MISSING, - }, - HttpStatus.BAD_REQUEST, - ); - } - } + private checkPasswordRequired( + foundConnectionToUpdate: ConnectionEntity, + newConnectionParameters: UpdateConnectionDs['connection_parameters'], + ): void { + if (this.isPasswordUpdateRequired(newConnectionParameters, foundConnectionToUpdate)) { + throw new HttpException( + { + message: Messages.PASSWORD_MISSING, + }, + HttpStatus.BAD_REQUEST, + ); + } + } - private isPasswordUpdateRequired( - newConnectionParameters: UpdateConnectionDs['connection_parameters'], - foundConnectionToUpdate: ConnectionEntity, - ): boolean { - const isTypeAgent = isConnectionTypeAgent(newConnectionParameters.type); - const isPasswordMissing = !newConnectionParameters.password; - const isHostOrPortChanged = - newConnectionParameters.host !== foundConnectionToUpdate.host || - newConnectionParameters.port !== foundConnectionToUpdate.port; + private isPasswordUpdateRequired( + newConnectionParameters: UpdateConnectionDs['connection_parameters'], + foundConnectionToUpdate: ConnectionEntity, + ): boolean { + const isTypeAgent = isConnectionTypeAgent(newConnectionParameters.type); + const isPasswordMissing = !newConnectionParameters.password; + const isHostOrPortChanged = + newConnectionParameters.host !== foundConnectionToUpdate.host || + newConnectionParameters.port !== foundConnectionToUpdate.port; - return newConnectionParameters.type && !isTypeAgent && isPasswordMissing && isHostOrPortChanged; - } + return newConnectionParameters.type && !isTypeAgent && isPasswordMissing && isHostOrPortChanged; + } - private async renewOrCreateConnectionToken(connectionId: string): Promise { - return await this._dbContext.agentRepository.renewOrCreateConnectionToken(connectionId); - } + private async renewOrCreateConnectionToken(connectionId: string): Promise { + return await this._dbContext.agentRepository.renewOrCreateConnectionToken(connectionId); + } - private clearNonRequiredConnectionAgentProperties(connection: ConnectionEntity): ConnectionEntity { - delete connection.masterEncryption; - delete connection.authSource; - delete connection.schema; - delete connection.sid; - delete connection.ssh; - delete connection.privateSSHKey; - delete connection.sshHost; - delete connection.sshPort; - delete connection.sshUsername; - delete connection.cert; - delete connection.azure_encryption; - delete connection.host; - delete connection.port; - delete connection.username; - delete connection.password; - delete connection.database; - return connection; - } + private clearNonRequiredConnectionAgentProperties(connection: ConnectionEntity): ConnectionEntity { + delete connection.masterEncryption; + delete connection.authSource; + delete connection.schema; + delete connection.sid; + delete connection.ssh; + delete connection.privateSSHKey; + delete connection.sshHost; + delete connection.sshPort; + delete connection.sshUsername; + delete connection.cert; + delete connection.azure_encryption; + delete connection.host; + delete connection.port; + delete connection.username; + delete connection.password; + delete connection.database; + return connection; + } } diff --git a/backend/src/entities/connection/use-cases/use-cases.interfaces.ts b/backend/src/entities/connection/use-cases/use-cases.interfaces.ts index 5bc4c8ee0..2d3df269f 100644 --- a/backend/src/entities/connection/use-cases/use-cases.interfaces.ts +++ b/backend/src/entities/connection/use-cases/use-cases.interfaces.ts @@ -1,103 +1,103 @@ -import { CreateConnectionDs } from '../application/data-structures/create-connection.ds.js'; -import { CreatedConnectionDTO } from '../application/dto/created-connection.dto.js'; +import { InTransactionEnum } from '../../../enums/index.js'; +import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; +import { FoundGroupResponseDto } from '../../group/dto/found-group-response.dto.js'; import { CreateUserDs } from '../../user/application/data-structures/create-user.ds.js'; -import { FindOneConnectionDs } from '../application/data-structures/find-one-connection.ds.js'; -import { FoundConnectionsDs } from '../application/data-structures/found-connections.ds.js'; import { FoundUserDto } from '../../user/dto/found-user.dto.js'; -import { UpdateConnectionDs } from '../application/data-structures/update-connection.ds.js'; +import { CreateConnectionDs } from '../application/data-structures/create-connection.ds.js'; +import { CreateGroupInConnectionDs } from '../application/data-structures/create-group-in-connection.ds.js'; import { DeleteConnectionDs } from '../application/data-structures/delete-connection.ds.js'; import { DeleteGroupInConnectionDs } from '../application/data-structures/delete-group-in-connection.ds.js'; -import { CreateGroupInConnectionDs } from '../application/data-structures/create-group-in-connection.ds.js'; +import { FindOneConnectionDs } from '../application/data-structures/find-one-connection.ds.js'; +import { FoundConnectionsDs } from '../application/data-structures/found-connections.ds.js'; +import { FoundOneConnectionDs } from '../application/data-structures/found-one-connection.ds.js'; +import { FoundPermissionsInConnectionDs } from '../application/data-structures/found-permissions-in-connection.ds.js'; import { GetGroupsInConnectionDs } from '../application/data-structures/get-groups-in-connection.ds.js'; import { GetPermissionsInConnectionDs } from '../application/data-structures/get-permissions-in-connection.ds.js'; -import { FoundPermissionsInConnectionDs } from '../application/data-structures/found-permissions-in-connection.ds.js'; -import { TestConnectionResultDs } from '../application/data-structures/test-connection-result.ds.js'; -import { UpdateMasterPasswordDs } from '../application/data-structures/update-master-password.ds.js'; import { RestoredConnectionDs } from '../application/data-structures/restored-connection.ds.js'; +import { TestConnectionResultDs } from '../application/data-structures/test-connection-result.ds.js'; import { TokenDs } from '../application/data-structures/token.ds.js'; -import { InTransactionEnum } from '../../../enums/index.js'; -import { FoundOneConnectionDs } from '../application/data-structures/found-one-connection.ds.js'; -import { FoundGroupResponseDto } from '../../group/dto/found-group-response.dto.js'; -import { FoundUserGroupsInConnectionDTO } from '../application/dto/found-user-groups-in-connection.dto.js'; -import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; -import { TokenValidationResult } from './validate-connection-token.use.case.js'; +import { UnfreezeConnectionDs } from '../application/data-structures/unfreeze-connection.ds.js'; +import { UpdateConnectionDs } from '../application/data-structures/update-connection.ds.js'; +import { UpdateMasterPasswordDs } from '../application/data-structures/update-master-password.ds.js'; import { ValidateConnectionMasterPasswordDs } from '../application/data-structures/validate-connection-master-password.ds.js'; +import { CreatedConnectionDTO } from '../application/dto/created-connection.dto.js'; +import { FoundUserGroupsInConnectionDTO } from '../application/dto/found-user-groups-in-connection.dto.js'; import { ValidationResultRo } from '../application/dto/validation-result.ro.js'; -import { UnfreezeConnectionDs } from '../application/data-structures/unfreeze-connection.ds.js'; +import { TokenValidationResult } from './validate-connection-token.use.case.js'; export interface IFindConnections { - execute(user: CreateUserDs, inTransaction: InTransactionEnum): Promise; + execute(user: CreateUserDs, inTransaction: InTransactionEnum): Promise; } export interface IFindUsersInConnection { - execute(connectionId: string, inTransaction: InTransactionEnum): Promise>; + execute(connectionId: string, inTransaction: InTransactionEnum): Promise>; } export interface IFindOneConnection { - execute(inputData: FindOneConnectionDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: FindOneConnectionDs, inTransaction: InTransactionEnum): Promise; } export interface ICreateConnection { - execute(inputData: CreateConnectionDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: CreateConnectionDs, inTransaction: InTransactionEnum): Promise; } export interface IUpdateConnection { - execute( - inputData: UpdateConnectionDs, - inTransaction: InTransactionEnum, - ): Promise>; + execute( + inputData: UpdateConnectionDs, + inTransaction: InTransactionEnum, + ): Promise>; } export interface IDeleteConnection { - execute(inputData: DeleteConnectionDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: DeleteConnectionDs, inTransaction: InTransactionEnum): Promise; } export interface IDeleteGroupInConnection { - execute(inputData: DeleteGroupInConnectionDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: DeleteGroupInConnectionDs, inTransaction: InTransactionEnum): Promise; } export interface ICreateGroupInConnection { - execute(inputData: CreateGroupInConnectionDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: CreateGroupInConnectionDs, inTransaction: InTransactionEnum): Promise; } export interface IGetUserGroupsInConnection { - execute( - inputData: GetGroupsInConnectionDs, - inTransaction: InTransactionEnum, - ): Promise>; + execute( + inputData: GetGroupsInConnectionDs, + inTransaction: InTransactionEnum, + ): Promise>; } export interface IGetPermissionsForGroupInConnection { - execute( - inputData: GetPermissionsInConnectionDs, - inTransaction: InTransactionEnum, - ): Promise; + execute( + inputData: GetPermissionsInConnectionDs, + inTransaction: InTransactionEnum, + ): Promise; } export interface ITestConnection { - execute(inputData: UpdateConnectionDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: UpdateConnectionDs, inTransaction: InTransactionEnum): Promise; } export interface IUpdateMasterPassword { - execute(inputData: UpdateMasterPasswordDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: UpdateMasterPasswordDs, inTransaction: InTransactionEnum): Promise; } export interface IRestoreConnection { - execute(inputData: UpdateConnectionDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: UpdateConnectionDs, inTransaction: InTransactionEnum): Promise; } export interface IValidateConnectionToken { - execute(token: string, inTransaction: InTransactionEnum): Promise; + execute(token: string, inTransaction: InTransactionEnum): Promise; } export interface IRefreshConnectionAgentToken { - execute(connectionId: string, inTransaction: InTransactionEnum): Promise; + execute(connectionId: string, inTransaction: InTransactionEnum): Promise; } export interface IValidateConnectionMasterPassword { - execute(inputData: ValidateConnectionMasterPasswordDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: ValidateConnectionMasterPasswordDs, inTransaction: InTransactionEnum): Promise; } export interface IUnfreezeConnection { - execute(inputData: UnfreezeConnectionDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: UnfreezeConnectionDs, inTransaction: InTransactionEnum): Promise; } diff --git a/backend/src/entities/connection/use-cases/validate-connection-master-password.use.case.ts b/backend/src/entities/connection/use-cases/validate-connection-master-password.use.case.ts index 591c9c232..79d1bdb39 100644 --- a/backend/src/entities/connection/use-cases/validate-connection-master-password.use.case.ts +++ b/backend/src/entities/connection/use-cases/validate-connection-master-password.use.case.ts @@ -1,46 +1,46 @@ -import { Injectable, Scope, Inject, InternalServerErrorException, BadRequestException } from '@nestjs/common'; +import { BadRequestException, Inject, Injectable, InternalServerErrorException, Scope } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { Encryptor } from '../../../helpers/encryption/encryptor.js'; import { ValidateConnectionMasterPasswordDs } from '../application/data-structures/validate-connection-master-password.ds.js'; +import { ValidationResultRo } from '../application/dto/validation-result.ro.js'; import { ConnectionEntity } from '../connection.entity.js'; import { IValidateConnectionMasterPassword } from './use-cases.interfaces.js'; -import { Encryptor } from '../../../helpers/encryption/encryptor.js'; -import { ValidationResultRo } from '../application/dto/validation-result.ro.js'; @Injectable({ scope: Scope.REQUEST }) export class ValidateConnectionMasterPasswordUseCase - extends AbstractUseCase - implements IValidateConnectionMasterPassword + extends AbstractUseCase + implements IValidateConnectionMasterPassword { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } - protected async implementation( - validateConnectionMasterPasswordData: ValidateConnectionMasterPasswordDs, - ): Promise { - const { connectionId, masterPassword } = validateConnectionMasterPasswordData; - const connection: ConnectionEntity = await this._dbContext.connectionRepository.findOne({ - where: { id: connectionId }, - }); + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } + protected async implementation( + validateConnectionMasterPasswordData: ValidateConnectionMasterPasswordDs, + ): Promise { + const { connectionId, masterPassword } = validateConnectionMasterPasswordData; + const connection: ConnectionEntity = await this._dbContext.connectionRepository.findOne({ + where: { id: connectionId }, + }); + + if (!connection) { + throw new InternalServerErrorException(Messages.CONNECTION_NOT_FOUND); + } - if (!connection) { - throw new InternalServerErrorException(Messages.CONNECTION_NOT_FOUND); - } + if (!connection.masterEncryption) { + throw new BadRequestException(Messages.CONNECTION_NOT_ENCRYPTED); + } - if (!connection.masterEncryption) { - throw new BadRequestException(Messages.CONNECTION_NOT_ENCRYPTED); - } + if (!connection.master_hash) { + throw new BadRequestException(Messages.CONNECTION_MASTER_PASSWORD_NOT_SET); + } - if (!connection.master_hash) { - throw new BadRequestException(Messages.CONNECTION_MASTER_PASSWORD_NOT_SET); - } - - const isMasterPasswordValid = await Encryptor.verifyUserPassword(masterPassword, connection.master_hash); - return { isValid: isMasterPasswordValid }; - } + const isMasterPasswordValid = await Encryptor.verifyUserPassword(masterPassword, connection.master_hash); + return { isValid: isMasterPasswordValid }; + } } diff --git a/backend/src/entities/connection/use-cases/validate-connection-token.use.case.ts b/backend/src/entities/connection/use-cases/validate-connection-token.use.case.ts index a92c66e0e..f831ca6d0 100644 --- a/backend/src/entities/connection/use-cases/validate-connection-token.use.case.ts +++ b/backend/src/entities/connection/use-cases/validate-connection-token.use.case.ts @@ -6,23 +6,23 @@ import { Encryptor } from '../../../helpers/encryption/encryptor.js'; import { IValidateConnectionToken } from './use-cases.interfaces.js'; export type TokenValidationResult = { - isValid: boolean; + isValid: boolean; }; @Injectable() export class ValidateConnectionTokenUseCase - extends AbstractUseCase - implements IValidateConnectionToken + extends AbstractUseCase + implements IValidateConnectionToken { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(connectionToken: string): Promise { - connectionToken = Encryptor.hashDataHMAC(connectionToken); - const foundConnection = await this._dbContext.connectionRepository.findOneAgentConnectionByToken(connectionToken); - return { isValid: !!foundConnection }; - } + protected async implementation(connectionToken: string): Promise { + connectionToken = Encryptor.hashDataHMAC(connectionToken); + const foundConnection = await this._dbContext.connectionRepository.findOneAgentConnectionByToken(connectionToken); + return { isValid: !!foundConnection }; + } } diff --git a/backend/src/entities/connection/utils/build-connection-entity.ts b/backend/src/entities/connection/utils/build-connection-entity.ts index 739b31e7c..3e17b1850 100644 --- a/backend/src/entities/connection/utils/build-connection-entity.ts +++ b/backend/src/entities/connection/utils/build-connection-entity.ts @@ -1,65 +1,65 @@ -import { ConnectionEntity } from '../connection.entity.js'; -import { CreateConnectionDs } from '../application/data-structures/create-connection.ds.js'; +import { Encryptor } from '../../../helpers/encryption/encryptor.js'; import { isConnectionTypeAgent } from '../../../helpers/index.js'; import { UserEntity } from '../../user/user.entity.js'; -import { Encryptor } from '../../../helpers/encryption/encryptor.js'; +import { CreateConnectionDs } from '../application/data-structures/create-connection.ds.js'; +import { ConnectionEntity } from '../connection.entity.js'; export async function buildConnectionEntity( - createConnectionData: CreateConnectionDs, - connectionAuthor: UserEntity, + createConnectionData: CreateConnectionDs, + connectionAuthor: UserEntity, ): Promise { - let connection: ConnectionEntity = new ConnectionEntity(); - const { - connection_parameters: { - azure_encryption, - cert, - masterEncryption, - port, - schema, - sid, - ssh, - sshHost, - sshPort, - ssl, - title, - host, - sshUsername, - username, - privateSSHKey, - database, - type, - password, - authSource, - dataCenter, - }, - creation_info: { masterPwd }, - } = createConnectionData; + let connection: ConnectionEntity = new ConnectionEntity(); + const { + connection_parameters: { + azure_encryption, + cert, + masterEncryption, + port, + schema, + sid, + ssh, + sshHost, + sshPort, + ssl, + title, + host, + sshUsername, + username, + privateSSHKey, + database, + type, + password, + authSource, + dataCenter, + }, + creation_info: { masterPwd }, + } = createConnectionData; - connection.title = title; - connection.type = type; - connection.ssh = ssh; - connection.ssl = ssl; - connection.azure_encryption = azure_encryption; - connection.author = connectionAuthor; - connection.masterEncryption = masterEncryption; - connection.host = host; - connection.port = port; - connection.username = username; - connection.password = password; - connection.database = database; - connection.sid = sid; - connection.privateSSHKey = privateSSHKey; - connection.sshHost = sshHost; - connection.sshPort = sshPort ? sshPort : undefined; - connection.sshUsername = sshUsername; - connection.cert = cert; - connection.schema = schema; - connection.authSource = authSource; - connection.dataCenter = dataCenter; + connection.title = title; + connection.type = type; + connection.ssh = ssh; + connection.ssl = ssl; + connection.azure_encryption = azure_encryption; + connection.author = connectionAuthor; + connection.masterEncryption = masterEncryption; + connection.host = host; + connection.port = port; + connection.username = username; + connection.password = password; + connection.database = database; + connection.sid = sid; + connection.privateSSHKey = privateSSHKey; + connection.sshHost = sshHost; + connection.sshPort = sshPort ? sshPort : undefined; + connection.sshUsername = sshUsername; + connection.cert = cert; + connection.schema = schema; + connection.authSource = authSource; + connection.dataCenter = dataCenter; - if (connection.masterEncryption && masterPwd && !isConnectionTypeAgent(connection.type)) { - connection = Encryptor.encryptConnectionCredentials(connection, masterPwd); - connection.master_hash = await Encryptor.hashUserPassword(masterPwd); - } - return connection; + if (connection.masterEncryption && masterPwd && !isConnectionTypeAgent(connection.type)) { + connection = Encryptor.encryptConnectionCredentials(connection, masterPwd); + connection.master_hash = await Encryptor.hashUserPassword(masterPwd); + } + return connection; } diff --git a/backend/src/entities/connection/utils/build-created-connection.ds.ts b/backend/src/entities/connection/utils/build-created-connection.ds.ts index a353702c2..68c2e4691 100644 --- a/backend/src/entities/connection/utils/build-created-connection.ds.ts +++ b/backend/src/entities/connection/utils/build-created-connection.ds.ts @@ -1,62 +1,62 @@ -import { ConnectionEntity } from '../connection.entity.js'; -import { CreatedConnectionDTO } from '../application/dto/created-connection.dto.js'; import { Encryptor } from '../../../helpers/encryption/encryptor.js'; +import { CreatedConnectionDTO } from '../application/dto/created-connection.dto.js'; +import { ConnectionEntity } from '../connection.entity.js'; export function buildCreatedConnectionDs( - connection: ConnectionEntity, - token: string, - masterPwd: string, + connection: ConnectionEntity, + token: string, + masterPwd: string, ): CreatedConnectionDTO { - if (connection.masterEncryption && masterPwd) { - connection = Encryptor.decryptConnectionCredentials(connection, masterPwd); - } - return { - author: connection.author?.id ? connection.author.id : undefined, - azure_encryption: connection.azure_encryption, - cert: connection.cert, - createdAt: connection.createdAt, - database: connection.database, - host: connection.host, - id: connection.id, - isTestConnection: connection.isTestConnection, - masterEncryption: connection.masterEncryption, - port: connection.port, - schema: connection.schema, - sid: connection.sid, - ssh: connection.ssh, - sshHost: connection.sshHost, - sshPort: connection.sshPort, - sshUsername: connection.sshUsername, - ssl: connection.ssl, - title: connection.title, - token: token ? token : null, - type: connection.type, - updatedAt: connection.updatedAt, - username: connection.username, - authSource: connection.authSource, - dataCenter: connection.dataCenter, - master_hash: connection.master_hash, - isFrozen: connection.is_frozen, - groups: connection.groups?.map((group) => { - return { - id: group.id, - title: group.title, - isMain: group.isMain, - users: group.users?.map((user) => { - return { - id: user.id, - isActive: user.isActive, - email: user.email, - createdAt: user.createdAt, - suspended: user.suspended, - name: user.name, - is_2fa_enabled: user.isOTPEnabled, - role: user.role, - externalRegistrationProvider: user.externalRegistrationProvider, - show_test_connections: user.showTestConnections, - }; - }), - }; - }), - }; + if (connection.masterEncryption && masterPwd) { + connection = Encryptor.decryptConnectionCredentials(connection, masterPwd); + } + return { + author: connection.author?.id ? connection.author.id : undefined, + azure_encryption: connection.azure_encryption, + cert: connection.cert, + createdAt: connection.createdAt, + database: connection.database, + host: connection.host, + id: connection.id, + isTestConnection: connection.isTestConnection, + masterEncryption: connection.masterEncryption, + port: connection.port, + schema: connection.schema, + sid: connection.sid, + ssh: connection.ssh, + sshHost: connection.sshHost, + sshPort: connection.sshPort, + sshUsername: connection.sshUsername, + ssl: connection.ssl, + title: connection.title, + token: token ? token : null, + type: connection.type, + updatedAt: connection.updatedAt, + username: connection.username, + authSource: connection.authSource, + dataCenter: connection.dataCenter, + master_hash: connection.master_hash, + isFrozen: connection.is_frozen, + groups: connection.groups?.map((group) => { + return { + id: group.id, + title: group.title, + isMain: group.isMain, + users: group.users?.map((user) => { + return { + id: user.id, + isActive: user.isActive, + email: user.email, + createdAt: user.createdAt, + suspended: user.suspended, + name: user.name, + is_2fa_enabled: user.isOTPEnabled, + role: user.role, + externalRegistrationProvider: user.externalRegistrationProvider, + show_test_connections: user.showTestConnections, + }; + }), + }; + }), + }; } diff --git a/backend/src/entities/connection/utils/build-found-connection.ds.ts b/backend/src/entities/connection/utils/build-found-connection.ds.ts index 6a0face13..0fffb24f8 100644 --- a/backend/src/entities/connection/utils/build-found-connection.ds.ts +++ b/backend/src/entities/connection/utils/build-found-connection.ds.ts @@ -1,40 +1,40 @@ import { - FoundAgentConnectionsDs, - FoundDirectConnectionsDs, - FoundDirectConnectionsNonePermissionDs, + FoundAgentConnectionsDs, + FoundDirectConnectionsDs, + FoundDirectConnectionsNonePermissionDs, } from '../application/data-structures/found-connections.ds.js'; import { ConnectionEntity } from '../connection.entity.js'; import { FilteredConnection } from '../use-cases/find-all-connections.use.case.js'; export function buildFoundConnectionDs( - connection: ConnectionEntity | FilteredConnection, + connection: ConnectionEntity | FilteredConnection, ): FoundDirectConnectionsDs | FoundAgentConnectionsDs | FoundDirectConnectionsNonePermissionDs { - return { - author: connection.author?.id, - azure_encryption: connection.azure_encryption, - cert: connection.cert, - createdAt: connection.createdAt, - database: connection.database, - host: connection.host, - id: connection.id, - masterEncryption: connection.masterEncryption, - port: connection.port, - schema: connection.schema, - sid: connection.sid, - ssh: connection.ssh, - sshHost: connection.sshHost, - sshPort: connection.sshPort, - ssl: connection.ssl, - title: connection.title, - token: connection.agent?.token, - type: connection.type, - updatedAt: connection.updatedAt, - username: connection.username, - signing_key: connection.signing_key, - isTestConnection: connection.isTestConnection, - connection_properties: connection.connection_properties, - isFrozen: connection.is_frozen, - authSource: connection.authSource ? connection.authSource : undefined, - dataCenter: connection.dataCenter ? connection.dataCenter : undefined, - }; + return { + author: connection.author?.id, + azure_encryption: connection.azure_encryption, + cert: connection.cert, + createdAt: connection.createdAt, + database: connection.database, + host: connection.host, + id: connection.id, + masterEncryption: connection.masterEncryption, + port: connection.port, + schema: connection.schema, + sid: connection.sid, + ssh: connection.ssh, + sshHost: connection.sshHost, + sshPort: connection.sshPort, + ssl: connection.ssl, + title: connection.title, + token: connection.agent?.token, + type: connection.type, + updatedAt: connection.updatedAt, + username: connection.username, + signing_key: connection.signing_key, + isTestConnection: connection.isTestConnection, + connection_properties: connection.connection_properties, + isFrozen: connection.is_frozen, + authSource: connection.authSource ? connection.authSource : undefined, + dataCenter: connection.dataCenter ? connection.dataCenter : undefined, + }; } diff --git a/backend/src/entities/connection/utils/build-found-user-group-in-connection-dto.util.ts b/backend/src/entities/connection/utils/build-found-user-group-in-connection-dto.util.ts index 66a922deb..ef2a8649b 100644 --- a/backend/src/entities/connection/utils/build-found-user-group-in-connection-dto.util.ts +++ b/backend/src/entities/connection/utils/build-found-user-group-in-connection-dto.util.ts @@ -4,16 +4,16 @@ import { buildSimpleUserInfoDs } from '../../user/utils/build-created-user.ds.js import { FoundUserGroupsInConnectionDTO } from '../application/dto/found-user-groups-in-connection.dto.js'; export function buildFoundUserGroupInConnectionDto( - group: GroupEntity, - accessLevel: AccessLevelEnum, + group: GroupEntity, + accessLevel: AccessLevelEnum, ): FoundUserGroupsInConnectionDTO { - return { - group: { - id: group.id, - title: group.title, - isMain: group.isMain, - users: group.users?.length ? group.users.map((user) => buildSimpleUserInfoDs(user)) : undefined, - }, - accessLevel, - }; + return { + group: { + id: group.id, + title: group.title, + isMain: group.isMain, + users: group.users?.length ? group.users.map((user) => buildSimpleUserInfoDs(user)) : undefined, + }, + accessLevel, + }; } diff --git a/backend/src/entities/connection/utils/build-new-group-entity-for-connection-with-user.ts b/backend/src/entities/connection/utils/build-new-group-entity-for-connection-with-user.ts index 0f2ee3ff2..4453e5869 100644 --- a/backend/src/entities/connection/utils/build-new-group-entity-for-connection-with-user.ts +++ b/backend/src/entities/connection/utils/build-new-group-entity-for-connection-with-user.ts @@ -1,17 +1,17 @@ -import { ConnectionEntity } from '../connection.entity.js'; -import { UserEntity } from '../../user/user.entity.js'; import { GroupEntity } from '../../group/group.entity.js'; +import { UserEntity } from '../../user/user.entity.js'; +import { ConnectionEntity } from '../connection.entity.js'; export function buildNewGroupEntityForConnectionWithUser( - connection: ConnectionEntity, - user: UserEntity, - groupTitle: string, + connection: ConnectionEntity, + user: UserEntity, + groupTitle: string, ): GroupEntity { - const newGroup = new GroupEntity(); - newGroup.title = groupTitle ? groupTitle : 'New group'; - newGroup.permissions = []; - newGroup.users = [user]; - newGroup.connection = connection; - newGroup.isMain = false; - return newGroup; + const newGroup = new GroupEntity(); + newGroup.title = groupTitle ? groupTitle : 'New group'; + newGroup.permissions = []; + newGroup.users = [user]; + newGroup.connection = connection; + newGroup.isMain = false; + return newGroup; } diff --git a/backend/src/entities/connection/utils/is-host-allowed.ts b/backend/src/entities/connection/utils/is-host-allowed.ts index 546d92ca8..e04156fc3 100644 --- a/backend/src/entities/connection/utils/is-host-allowed.ts +++ b/backend/src/entities/connection/utils/is-host-allowed.ts @@ -1,45 +1,45 @@ import dns from 'dns'; import ipRangeCheck from 'ip-range-check'; +import { isSaaS } from '../../../helpers/app/is-saas.js'; import { Constants } from '../../../helpers/constants/constants.js'; import { isConnectionEntityAgent } from '../../../helpers/index.js'; -import { isSaaS } from '../../../helpers/app/is-saas.js'; import { CreateConnectionDto } from '../application/dto/create-connection.dto.js'; export async function isHostAllowed(connectionData: CreateConnectionDto): Promise { - if (isConnectionEntityAgent(connectionData) || process.env.NODE_ENV === 'test') { - return true; - } - if (process.env.NODE_ENV !== 'test' && !isSaaS()) { - return true; - } + if (isConnectionEntityAgent(connectionData) || process.env.NODE_ENV === 'test') { + return true; + } + if (process.env.NODE_ENV !== 'test' && !isSaaS()) { + return true; + } - return new Promise((resolve, reject) => { - const testHosts = Constants.getTestConnectionsHostNamesArr(); - if (!connectionData.ssh) { - dns.lookup(connectionData.host, (err, address) => { - if (ipRangeCheck(address, Constants.FORBIDDEN_HOSTS) && !testHosts.includes(connectionData.host)) { - resolve(false); - } else { - resolve(true); - } - if (err) { - reject(err); - } - }); - } else if (connectionData.ssh && connectionData.sshHost) { - dns.lookup(connectionData.sshHost, (err, address) => { - if (ipRangeCheck(address, Constants.FORBIDDEN_HOSTS) && !testHosts.includes(connectionData.host)) { - resolve(false); - } else { - resolve(true); - } - if (err) { - reject(err); - } - }); - } - }).catch((e) => { - console.error('DNS lookup error message', e.message); - return false; - }); + return new Promise((resolve, reject) => { + const testHosts = Constants.getTestConnectionsHostNamesArr(); + if (!connectionData.ssh) { + dns.lookup(connectionData.host, (err, address) => { + if (ipRangeCheck(address, Constants.FORBIDDEN_HOSTS) && !testHosts.includes(connectionData.host)) { + resolve(false); + } else { + resolve(true); + } + if (err) { + reject(err); + } + }); + } else if (connectionData.ssh && connectionData.sshHost) { + dns.lookup(connectionData.sshHost, (err, address) => { + if (ipRangeCheck(address, Constants.FORBIDDEN_HOSTS) && !testHosts.includes(connectionData.host)) { + resolve(false); + } else { + resolve(true); + } + if (err) { + reject(err); + } + }); + } + }).catch((e) => { + console.error('DNS lookup error message', e.message); + return false; + }); } diff --git a/backend/src/entities/connection/utils/is-test-connection-util.ts b/backend/src/entities/connection/utils/is-test-connection-util.ts index fac82512a..77a7098bd 100644 --- a/backend/src/entities/connection/utils/is-test-connection-util.ts +++ b/backend/src/entities/connection/utils/is-test-connection-util.ts @@ -3,13 +3,13 @@ import { CreatedConnectionDTO } from '../application/dto/created-connection.dto. import { ConnectionEntity } from '../connection.entity.js'; export function isTestConnectionUtil(connection: ConnectionEntity | CreatedConnectionDTO): boolean { - if (connection.isTestConnection) { - return true; - } - return isHostTest(connection.host); + if (connection.isTestConnection) { + return true; + } + return isHostTest(connection.host); } export function isHostTest(hostname: string): boolean { - const testConnectionsHosts = Constants.getTestConnectionsArr().map((el) => el.host); - return testConnectionsHosts.includes(hostname); + const testConnectionsHosts = Constants.getTestConnectionsArr().map((el) => el.host); + return testConnectionsHosts.includes(hostname); } diff --git a/backend/src/entities/connection/utils/process-aws-connection.util.ts b/backend/src/entities/connection/utils/process-aws-connection.util.ts index 4df9c011d..671ef3afc 100644 --- a/backend/src/entities/connection/utils/process-aws-connection.util.ts +++ b/backend/src/entities/connection/utils/process-aws-connection.util.ts @@ -3,36 +3,36 @@ import { CreateConnectionDs } from '../application/data-structures/create-connec import { readSslCertificate } from '../ssl-certificate/read-certificate.js'; export async function processAWSConnection(createConnectionData: CreateConnectionDs): Promise { - if (isConnectionTypeAgent(createConnectionData.connection_parameters.type)) { - return createConnectionData; - } - const { host } = createConnectionData.connection_parameters; + if (isConnectionTypeAgent(createConnectionData.connection_parameters.type)) { + return createConnectionData; + } + const { host } = createConnectionData.connection_parameters; - if (host.endsWith('.rds.amazonaws.com')) { - createConnectionData.connection_parameters.ssl = true; - createConnectionData.connection_parameters.cert = await readSslCertificate(); - return createConnectionData; - } + if (host.endsWith('.rds.amazonaws.com')) { + createConnectionData.connection_parameters.ssl = true; + createConnectionData.connection_parameters.cert = await readSslCertificate(); + return createConnectionData; + } - if (host.includes('amazonaws.com') && host.includes('ec2-') && host.endsWith('.compute.amazonaws.com')) { - createConnectionData.connection_parameters.ssl = true; - createConnectionData.connection_parameters.cert = await readSslCertificate(); - return createConnectionData; - } + if (host.includes('amazonaws.com') && host.includes('ec2-') && host.endsWith('.compute.amazonaws.com')) { + createConnectionData.connection_parameters.ssl = true; + createConnectionData.connection_parameters.cert = await readSslCertificate(); + return createConnectionData; + } - const rdsHostRegex = /^[^.]+[.][^.]+[.](rds[.].+[.]amazonaws[.]com)$/i; - if (rdsHostRegex.test(host)) { - createConnectionData.connection_parameters.ssl = true; - createConnectionData.connection_parameters.cert = await readSslCertificate(); - return createConnectionData; - } + const rdsHostRegex = /^[^.]+[.][^.]+[.](rds[.].+[.]amazonaws[.]com)$/i; + if (rdsHostRegex.test(host)) { + createConnectionData.connection_parameters.ssl = true; + createConnectionData.connection_parameters.cert = await readSslCertificate(); + return createConnectionData; + } - const ec2HostRegex = /^(ec2-).*([.]compute[.]amazonaws[.]com)$/i; - if (ec2HostRegex.test(host)) { - createConnectionData.connection_parameters.ssl = true; - createConnectionData.connection_parameters.cert = await readSslCertificate(); - return createConnectionData; - } + const ec2HostRegex = /^(ec2-).*([.]compute[.]amazonaws[.]com)$/i; + if (ec2HostRegex.test(host)) { + createConnectionData.connection_parameters.ssl = true; + createConnectionData.connection_parameters.cert = await readSslCertificate(); + return createConnectionData; + } - return createConnectionData; + return createConnectionData; } diff --git a/backend/src/entities/connection/utils/update-connection-entity-for-restoration.ts b/backend/src/entities/connection/utils/update-connection-entity-for-restoration.ts index deab25024..47c548b30 100644 --- a/backend/src/entities/connection/utils/update-connection-entity-for-restoration.ts +++ b/backend/src/entities/connection/utils/update-connection-entity-for-restoration.ts @@ -1,61 +1,61 @@ -import { ConnectionEntity } from '../connection.entity.js'; -import { UpdateConnectionDs } from '../application/data-structures/update-connection.ds.js'; -import { isConnectionEntityAgent } from '../../../helpers/index.js'; import { Encryptor } from '../../../helpers/encryption/encryptor.js'; +import { isConnectionEntityAgent } from '../../../helpers/index.js'; +import { UpdateConnectionDs } from '../application/data-structures/update-connection.ds.js'; +import { ConnectionEntity } from '../connection.entity.js'; export async function updateConnectionEntityForRestoration( - toUpdate: ConnectionEntity, - updateParameters: UpdateConnectionDs, - isTestConnection: boolean, + toUpdate: ConnectionEntity, + updateParameters: UpdateConnectionDs, + isTestConnection: boolean, ): Promise { - const { - connection_parameters, - update_info: { masterPwd }, - } = updateParameters; - toUpdate.title = connection_parameters.title; - toUpdate.type = connection_parameters.type; - toUpdate.ssh = connection_parameters.ssh; - toUpdate.ssl = connection_parameters.ssl; - toUpdate.isTestConnection = isTestConnection; - if (!isConnectionEntityAgent(connection_parameters)) { - toUpdate.masterEncryption = connection_parameters.masterEncryption; - toUpdate.host = connection_parameters.host; - toUpdate.port = connection_parameters.port; - toUpdate.username = - connection_parameters.masterEncryption && masterPwd - ? Encryptor.encryptDataMasterPwd(connection_parameters.username, masterPwd) - : connection_parameters.username; - toUpdate.password = - connection_parameters.masterEncryption && masterPwd - ? Encryptor.encryptDataMasterPwd(connection_parameters.password, masterPwd) - : connection_parameters.password; - toUpdate.database = - connection_parameters.masterEncryption && masterPwd - ? Encryptor.encryptDataMasterPwd(connection_parameters.database, masterPwd) - : connection_parameters.database; - toUpdate.sid = connection_parameters.sid; - toUpdate.privateSSHKey = - connection_parameters.masterEncryption && masterPwd - ? Encryptor.encryptDataMasterPwd(connection_parameters.privateSSHKey, masterPwd) - : connection_parameters.privateSSHKey; - toUpdate.sshHost = - connection_parameters.masterEncryption && masterPwd - ? Encryptor.encryptDataMasterPwd(connection_parameters.sshHost, masterPwd) - : connection_parameters.sshHost; - toUpdate.sshPort = connection_parameters.sshPort ? connection_parameters.sshPort : undefined; - toUpdate.sshUsername = - connection_parameters.masterEncryption && masterPwd - ? Encryptor.encryptDataMasterPwd(connection_parameters.sshUsername, masterPwd) - : connection_parameters.sshUsername; - toUpdate.cert = connection_parameters.cert; - toUpdate.schema = connection_parameters.schema; - toUpdate.azure_encryption = connection_parameters.azure_encryption; - toUpdate.authSource = - connection_parameters.masterEncryption && masterPwd - ? Encryptor.encryptDataMasterPwd(connection_parameters.authSource, masterPwd) - : connection_parameters.authSource; - toUpdate.master_hash = - connection_parameters.masterEncryption && masterPwd ? await Encryptor.hashUserPassword(masterPwd) : undefined; - } - return toUpdate; + const { + connection_parameters, + update_info: { masterPwd }, + } = updateParameters; + toUpdate.title = connection_parameters.title; + toUpdate.type = connection_parameters.type; + toUpdate.ssh = connection_parameters.ssh; + toUpdate.ssl = connection_parameters.ssl; + toUpdate.isTestConnection = isTestConnection; + if (!isConnectionEntityAgent(connection_parameters)) { + toUpdate.masterEncryption = connection_parameters.masterEncryption; + toUpdate.host = connection_parameters.host; + toUpdate.port = connection_parameters.port; + toUpdate.username = + connection_parameters.masterEncryption && masterPwd + ? Encryptor.encryptDataMasterPwd(connection_parameters.username, masterPwd) + : connection_parameters.username; + toUpdate.password = + connection_parameters.masterEncryption && masterPwd + ? Encryptor.encryptDataMasterPwd(connection_parameters.password, masterPwd) + : connection_parameters.password; + toUpdate.database = + connection_parameters.masterEncryption && masterPwd + ? Encryptor.encryptDataMasterPwd(connection_parameters.database, masterPwd) + : connection_parameters.database; + toUpdate.sid = connection_parameters.sid; + toUpdate.privateSSHKey = + connection_parameters.masterEncryption && masterPwd + ? Encryptor.encryptDataMasterPwd(connection_parameters.privateSSHKey, masterPwd) + : connection_parameters.privateSSHKey; + toUpdate.sshHost = + connection_parameters.masterEncryption && masterPwd + ? Encryptor.encryptDataMasterPwd(connection_parameters.sshHost, masterPwd) + : connection_parameters.sshHost; + toUpdate.sshPort = connection_parameters.sshPort ? connection_parameters.sshPort : undefined; + toUpdate.sshUsername = + connection_parameters.masterEncryption && masterPwd + ? Encryptor.encryptDataMasterPwd(connection_parameters.sshUsername, masterPwd) + : connection_parameters.sshUsername; + toUpdate.cert = connection_parameters.cert; + toUpdate.schema = connection_parameters.schema; + toUpdate.azure_encryption = connection_parameters.azure_encryption; + toUpdate.authSource = + connection_parameters.masterEncryption && masterPwd + ? Encryptor.encryptDataMasterPwd(connection_parameters.authSource, masterPwd) + : connection_parameters.authSource; + toUpdate.master_hash = + connection_parameters.masterEncryption && masterPwd ? await Encryptor.hashUserPassword(masterPwd) : undefined; + } + return toUpdate; } diff --git a/backend/src/entities/connection/utils/validate-create-connection-data.ts b/backend/src/entities/connection/utils/validate-create-connection-data.ts index eb7e37f3e..1d5d65873 100644 --- a/backend/src/entities/connection/utils/validate-create-connection-data.ts +++ b/backend/src/entities/connection/utils/validate-create-connection-data.ts @@ -1,8 +1,8 @@ import { HttpStatus } from '@nestjs/common'; import { HttpException } from '@nestjs/common/exceptions/http.exception.js'; import { - ConnectionTypesEnum, - ConnectionTypeTestEnum, + ConnectionTypesEnum, + ConnectionTypeTestEnum, } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; import dns from 'dns'; import ipRangeCheck from 'ip-range-check'; @@ -14,121 +14,121 @@ import { CreateConnectionDs } from '../application/data-structures/create-connec import { UpdateConnectionDs } from '../application/data-structures/update-connection.ds.js'; export async function validateCreateConnectionData( - createConnectionData: CreateConnectionDs | UpdateConnectionDs, + createConnectionData: CreateConnectionDs | UpdateConnectionDs, ): Promise { - const { - connection_parameters: { port, ssh, sshHost, sshPort, title, host, sshUsername, username, database, type }, - } = createConnectionData; - const errors: Array = []; - if (!type) errors.push(Messages.TYPE_MISSING); - if (!validateConnectionType(type)) errors.push(Messages.CONNECTION_TYPE_INVALID); - if (!isConnectionTypeAgent(type)) { - if (!host) { - errors.push(Messages.HOST_MISSING); - } - // if (ssh) { - // if (!validator.isFQDN(host) && !validator.isIP(host) && !host.includes('localhost') && !host.includes('127.0.0.1')) { - // errors.push(Messages.HOST_NAME_INVALID); - // throw new HttpException( - // { - // message: toPrettyErrorsMsg(errors), - // }, - // HttpStatus.BAD_REQUEST, - // ); - // } - // } - if (!username && type !== ConnectionTypesEnum.redis) errors.push(Messages.USERNAME_MISSING); + const { + connection_parameters: { port, ssh, sshHost, sshPort, title, host, sshUsername, username, database, type }, + } = createConnectionData; + const errors: Array = []; + if (!type) errors.push(Messages.TYPE_MISSING); + if (!validateConnectionType(type)) errors.push(Messages.CONNECTION_TYPE_INVALID); + if (!isConnectionTypeAgent(type)) { + if (!host) { + errors.push(Messages.HOST_MISSING); + } + // if (ssh) { + // if (!validator.isFQDN(host) && !validator.isIP(host) && !host.includes('localhost') && !host.includes('127.0.0.1')) { + // errors.push(Messages.HOST_NAME_INVALID); + // throw new HttpException( + // { + // message: toPrettyErrorsMsg(errors), + // }, + // HttpStatus.BAD_REQUEST, + // ); + // } + // } + if (!username && type !== ConnectionTypesEnum.redis) errors.push(Messages.USERNAME_MISSING); - if ( - type !== ConnectionTypesEnum.dynamodb && - type !== ConnectionTypesEnum.elasticsearch && - type !== ConnectionTypesEnum.redis - ) { - if (!database) errors.push(Messages.DATABASE_MISSING); - if (port < 0 || port > 65535 || !port) errors.push(Messages.PORT_MISSING); - if (typeof port !== 'number') errors.push(Messages.PORT_FORMAT_INCORRECT); - if (typeof ssh !== 'boolean') errors.push(Messages.SSH_FORMAT_INCORRECT); - if (ssh) { - if (typeof sshPort !== 'number') { - errors.push(Messages.SSH_PORT_FORMAT_INCORRECT); - } - if (!sshPort) errors.push(Messages.SSH_PORT_MISSING); - if (!sshUsername) errors.push(Messages.SSH_USERNAME_MISSING); - if (!sshHost) errors.push(Messages.SSH_HOST_MISSING); - } - } - } else { - if (!title) errors.push('Connection title missing'); - } + if ( + type !== ConnectionTypesEnum.dynamodb && + type !== ConnectionTypesEnum.elasticsearch && + type !== ConnectionTypesEnum.redis + ) { + if (!database) errors.push(Messages.DATABASE_MISSING); + if (port < 0 || port > 65535 || !port) errors.push(Messages.PORT_MISSING); + if (typeof port !== 'number') errors.push(Messages.PORT_FORMAT_INCORRECT); + if (typeof ssh !== 'boolean') errors.push(Messages.SSH_FORMAT_INCORRECT); + if (ssh) { + if (typeof sshPort !== 'number') { + errors.push(Messages.SSH_PORT_FORMAT_INCORRECT); + } + if (!sshPort) errors.push(Messages.SSH_PORT_MISSING); + if (!sshUsername) errors.push(Messages.SSH_USERNAME_MISSING); + if (!sshHost) errors.push(Messages.SSH_HOST_MISSING); + } + } + } else { + if (!title) errors.push('Connection title missing'); + } - if (errors.length > 0) { - throw new HttpException( - { - message: toPrettyErrorsMsg(errors), - }, - HttpStatus.BAD_REQUEST, - ); - } else { - const checkingResult = await checkIsHostAllowed(createConnectionData); - if (!checkingResult) { - throw new HttpException( - { - message: Messages.CANNOT_CREATE_CONNECTION_TO_THIS_HOST, - }, - HttpStatus.FORBIDDEN, - ); - } - return true; - } + if (errors.length > 0) { + throw new HttpException( + { + message: toPrettyErrorsMsg(errors), + }, + HttpStatus.BAD_REQUEST, + ); + } else { + const checkingResult = await checkIsHostAllowed(createConnectionData); + if (!checkingResult) { + throw new HttpException( + { + message: Messages.CANNOT_CREATE_CONNECTION_TO_THIS_HOST, + }, + HttpStatus.FORBIDDEN, + ); + } + return true; + } } function validateConnectionType(type: string): string { - if (process.env.NODE_ENV === 'test') { - return Object.keys(ConnectionTypeTestEnum).find((key) => key === type); - } - return Object.keys(ConnectionTypesEnum).find((key) => key === type); + if (process.env.NODE_ENV === 'test') { + return Object.keys(ConnectionTypeTestEnum).find((key) => key === type); + } + return Object.keys(ConnectionTypesEnum).find((key) => key === type); } async function checkIsHostAllowed(createConnectionData: CreateConnectionDs | UpdateConnectionDs): Promise { - if (isConnectionTypeAgent(createConnectionData.connection_parameters.type) || process.env.NODE_ENV === 'test') { - return true; - } - if (process.env.NODE_ENV !== 'test' && !isSaaS()) { - return true; - } - return new Promise((resolve, reject) => { - const testHosts = Constants.getTestConnectionsHostNamesArr(); - if (!createConnectionData.connection_parameters.ssh) { - dns.lookup(createConnectionData.connection_parameters.host, (err, address) => { - if ( - ipRangeCheck(address, Constants.FORBIDDEN_HOSTS) && - !testHosts.includes(createConnectionData.connection_parameters.host) - ) { - resolve(false); - } else { - resolve(true); - } - if (err) { - reject(err); - } - }); - } else if (createConnectionData.connection_parameters.ssh && createConnectionData.connection_parameters.sshHost) { - dns.lookup(createConnectionData.connection_parameters.sshHost, (err, address) => { - if ( - ipRangeCheck(address, Constants.FORBIDDEN_HOSTS) && - !testHosts.includes(createConnectionData.connection_parameters.host) - ) { - resolve(false); - } else { - resolve(true); - } - if (err) { - reject(err); - } - }); - } - }).catch((e) => { - console.error('DNS lookup error message', e.message); - return false; - }); + if (isConnectionTypeAgent(createConnectionData.connection_parameters.type) || process.env.NODE_ENV === 'test') { + return true; + } + if (process.env.NODE_ENV !== 'test' && !isSaaS()) { + return true; + } + return new Promise((resolve, reject) => { + const testHosts = Constants.getTestConnectionsHostNamesArr(); + if (!createConnectionData.connection_parameters.ssh) { + dns.lookup(createConnectionData.connection_parameters.host, (err, address) => { + if ( + ipRangeCheck(address, Constants.FORBIDDEN_HOSTS) && + !testHosts.includes(createConnectionData.connection_parameters.host) + ) { + resolve(false); + } else { + resolve(true); + } + if (err) { + reject(err); + } + }); + } else if (createConnectionData.connection_parameters.ssh && createConnectionData.connection_parameters.sshHost) { + dns.lookup(createConnectionData.connection_parameters.sshHost, (err, address) => { + if ( + ipRangeCheck(address, Constants.FORBIDDEN_HOSTS) && + !testHosts.includes(createConnectionData.connection_parameters.host) + ) { + resolve(false); + } else { + resolve(true); + } + if (err) { + reject(err); + } + }); + } + }).catch((e) => { + console.error('DNS lookup error message', e.message); + return false; + }); } diff --git a/backend/src/entities/convention/conversion.controller.ts b/backend/src/entities/convention/conversion.controller.ts index 90a4cc1c9..15abfab30 100644 --- a/backend/src/entities/convention/conversion.controller.ts +++ b/backend/src/entities/convention/conversion.controller.ts @@ -2,10 +2,10 @@ import { Controller, Get, Inject, Injectable, Res, UseInterceptors } from '@nest import { ApiBearerAuth, ApiTags } from '@nestjs/swagger'; import { Response } from 'express'; import { UseCaseType } from '../../common/data-injection.tokens.js'; +import { Timeout } from '../../decorators/timeout.decorator.js'; import { InTransactionEnum } from '../../enums/index.js'; import { SentryInterceptor } from '../../interceptors/index.js'; import { IGetConversions } from './use-cases/get-conversions-use-cases.interface.js'; -import { Timeout } from '../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/convention/conversion.module.ts b/backend/src/entities/convention/conversion.module.ts index 99e5ff4db..010a5c270 100644 --- a/backend/src/entities/convention/conversion.module.ts +++ b/backend/src/entities/convention/conversion.module.ts @@ -1,30 +1,30 @@ -import { BasicAuthMiddleware } from '../../authorization/index.js'; -import { ConnectionEntity } from '../connection/connection.entity.js'; -import { ConversionController } from './conversion.controller.js'; import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { UserEntity } from '../user/user.entity.js'; -import { TableLogsEntity } from '../table-logs/table-logs.entity.js'; -import { GetConversionsUseCase } from './use-cases/get-conversions.use.case.js'; +import { BasicAuthMiddleware } from '../../authorization/index.js'; import { GlobalDatabaseContext } from '../../common/application/global-database-context.js'; import { BaseType, UseCaseType } from '../../common/data-injection.tokens.js'; +import { ConnectionEntity } from '../connection/connection.entity.js'; +import { TableLogsEntity } from '../table-logs/table-logs.entity.js'; +import { UserEntity } from '../user/user.entity.js'; +import { ConversionController } from './conversion.controller.js'; +import { GetConversionsUseCase } from './use-cases/get-conversions.use.case.js'; @Module({ - imports: [TypeOrmModule.forFeature([ConnectionEntity, UserEntity, TableLogsEntity])], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.GET_CONVERSIONS, - useClass: GetConversionsUseCase, - }, - ], - controllers: [ConversionController], + imports: [TypeOrmModule.forFeature([ConnectionEntity, UserEntity, TableLogsEntity])], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.GET_CONVERSIONS, + useClass: GetConversionsUseCase, + }, + ], + controllers: [ConversionController], }) export class ConversionModule implements NestModule { - public configure(consumer: MiddlewareConsumer): any { - consumer.apply(BasicAuthMiddleware).forRoutes({ path: '/conversions', method: RequestMethod.GET }); - } + public configure(consumer: MiddlewareConsumer): any { + consumer.apply(BasicAuthMiddleware).forRoutes({ path: '/conversions', method: RequestMethod.GET }); + } } diff --git a/backend/src/entities/convention/use-cases/get-conversions-use-cases.interface.ts b/backend/src/entities/convention/use-cases/get-conversions-use-cases.interface.ts index b1bd0eb4c..316c50de6 100644 --- a/backend/src/entities/convention/use-cases/get-conversions-use-cases.interface.ts +++ b/backend/src/entities/convention/use-cases/get-conversions-use-cases.interface.ts @@ -1,5 +1,5 @@ import { InTransactionEnum } from '../../../enums/index.js'; export interface IGetConversions { - execute(inputData: undefined, inTransaction: InTransactionEnum): Promise; + execute(inputData: undefined, inTransaction: InTransactionEnum): Promise; } diff --git a/backend/src/entities/convention/use-cases/get-conversions.use.case.ts b/backend/src/entities/convention/use-cases/get-conversions.use.case.ts index 31141b9db..192ed5c43 100644 --- a/backend/src/entities/convention/use-cases/get-conversions.use.case.ts +++ b/backend/src/entities/convention/use-cases/get-conversions.use.case.ts @@ -7,39 +7,39 @@ import { IGetConversions } from './get-conversions-use-cases.interface.js'; @Injectable() export class GetConversionsUseCase extends AbstractUseCase implements IGetConversions { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(): Promise { - const freshUsers = await this._dbContext.userRepository.getUsersWithNotNullGCLIDsInTwoWeeks(); - const workedFreshConnections = await this._dbContext.connectionRepository.getWorkedConnectionsInTwoWeeks(); + protected async implementation(): Promise { + const freshUsers = await this._dbContext.userRepository.getUsersWithNotNullGCLIDsInTwoWeeks(); + const workedFreshConnections = await this._dbContext.connectionRepository.getWorkedConnectionsInTwoWeeks(); - const conversionsArray = []; + const conversionsArray = []; - for (const user of freshUsers) { - conversionsArray.push({ - "Google Click ID": user.gclid, - "Conversion Name": 'Registration', - "Conversion Time": user.createdAt, - }); - } + for (const user of freshUsers) { + conversionsArray.push({ + 'Google Click ID': user.gclid, + 'Conversion Name': 'Registration', + 'Conversion Time': user.createdAt, + }); + } - for (const connection of workedFreshConnections) { - conversionsArray.push({ - "Google Click ID": connection.author.gclid, - "Conversion Name": 'Connection added', - "Conversion Time": connection.createdAt, - }); - } + for (const connection of workedFreshConnections) { + conversionsArray.push({ + 'Google Click ID': connection.author.gclid, + 'Conversion Name': 'Connection added', + 'Conversion Time': connection.createdAt, + }); + } - const fields = ['Google Click ID', 'Conversion Name', 'Conversion Time']; - const head = 'Parameters:TimeZone=-0500' + '\r\n'; - const csvParser = new CsvParser({ fields }); - const csvData: string = csvParser.parse(conversionsArray); - return head + csvData; - } + const fields = ['Google Click ID', 'Conversion Name', 'Conversion Time']; + const head = 'Parameters:TimeZone=-0500' + '\r\n'; + const csvParser = new CsvParser({ fields }); + const csvData: string = csvParser.parse(conversionsArray); + return head + csvData; + } } diff --git a/backend/src/entities/cron-jobs/cron-jobs.module.ts b/backend/src/entities/cron-jobs/cron-jobs.module.ts index 12728c491..f1614f544 100644 --- a/backend/src/entities/cron-jobs/cron-jobs.module.ts +++ b/backend/src/entities/cron-jobs/cron-jobs.module.ts @@ -2,28 +2,28 @@ import { Global, Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { UseCaseType } from '../../common/data-injection.tokens.js'; import { TableLogsEntity } from '../table-logs/table-logs.entity.js'; +import { UserEntity } from '../user/user.entity.js'; import { CheckUsersActionsAndMailingUsersUseCase } from '../user-actions/use-cases/check-users-actions-and-mailing-users.use.case.js'; import { CheckUsersLogsAndUpdateActionsUseCase } from '../user-actions/use-cases/check-users-logs-and-update-actions.use.case.js'; import { UserActionEntity } from '../user-actions/user-action.entity.js'; import { UserActionModule } from '../user-actions/user-action.module.js'; -import { UserEntity } from '../user/user.entity.js'; import { CronJobsService } from './cron-jobs.service.js'; import { JobListEntity } from './job-list.entity.js'; @Global() @Module({ - imports: [TypeOrmModule.forFeature([UserActionEntity, UserEntity, JobListEntity, TableLogsEntity]), UserActionModule], - providers: [ - CronJobsService, - { - provide: UseCaseType.CHECK_USER_LOGS_AND_UPDATE_ACTIONS, - useClass: CheckUsersLogsAndUpdateActionsUseCase, - }, - { - provide: UseCaseType.CHECK_USER_ACTIONS_AND_MAIL_USERS, - useClass: CheckUsersActionsAndMailingUsersUseCase, - }, - ], - exports: [CronJobsService], + imports: [TypeOrmModule.forFeature([UserActionEntity, UserEntity, JobListEntity, TableLogsEntity]), UserActionModule], + providers: [ + CronJobsService, + { + provide: UseCaseType.CHECK_USER_LOGS_AND_UPDATE_ACTIONS, + useClass: CheckUsersLogsAndUpdateActionsUseCase, + }, + { + provide: UseCaseType.CHECK_USER_ACTIONS_AND_MAIL_USERS, + useClass: CheckUsersActionsAndMailingUsersUseCase, + }, + ], + exports: [CronJobsService], }) export class CronJobsModule {} diff --git a/backend/src/entities/cron-jobs/cron-jobs.service.ts b/backend/src/entities/cron-jobs/cron-jobs.service.ts index a13d3e625..4a4ece987 100644 --- a/backend/src/entities/cron-jobs/cron-jobs.service.ts +++ b/backend/src/entities/cron-jobs/cron-jobs.service.ts @@ -9,198 +9,198 @@ import { slackPostMessage } from '../../helpers/index.js'; import { ValidationHelper } from '../../helpers/validators/validation-helper.js'; import { EmailService, ICronMessagingResults } from '../email/email/email.service.js'; import { - ICheckUsersActionsAndMailingUsers, - ICheckUsersLogsAndUpdateActionsUseCase, + ICheckUsersActionsAndMailingUsers, + ICheckUsersLogsAndUpdateActionsUseCase, } from '../user-actions/use-cases/use-cases-interfaces.js'; import { JobListEntity } from './job-list.entity.js'; @Injectable() export class CronJobsService { - constructor( - @Inject(UseCaseType.CHECK_USER_LOGS_AND_UPDATE_ACTIONS) - private readonly checkUsersLogsAndUpdateActionsUseCase: ICheckUsersLogsAndUpdateActionsUseCase, - @Inject(UseCaseType.CHECK_USER_ACTIONS_AND_MAIL_USERS) - private readonly checkUsersActionsAndMailingUsersUseCase: ICheckUsersActionsAndMailingUsers, - @InjectRepository(JobListEntity) - private readonly jobListRepository: Repository, - private readonly emailService: EmailService, - ) {} - - @Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT) - async handleCron(): Promise { - try { - const isJobAdded = await this.insertMidnightJob(); - if (!isJobAdded) { - return; - } - await slackPostMessage(`midnight cron started at ${this.getCurrentTime()}`, Constants.EXCEPTIONS_CHANNELS); - await this.checkUsersLogsAndUpdateActionsUseCase.execute(); - await slackPostMessage(`midnight cron finished at ${this.getCurrentTime()}`, Constants.EXCEPTIONS_CHANNELS); - } catch (e) { - Sentry.captureException(e); - console.error(e); - } - } - - @Cron(CronExpression.EVERY_DAY_AT_8AM) - async handleMailingCron(): Promise { - try { - const isJobAdded = await this.insertMorningJob(); - if (!isJobAdded) { - console.log('Job already in progress, exiting'); - return; - } - - await slackPostMessage(`Email cron started at ${this.getCurrentTime()}`, Constants.EXCEPTIONS_CHANNELS); - - try { - let emails = await this.checkUsersActionsAndMailingUsersUseCase.execute(); - await slackPostMessage( - `Retrieved ${emails.length} email addresses from database`, - Constants.EXCEPTIONS_CHANNELS, - ); - - const emailsBefore = emails.length; - emails = emails.filter((email) => { - return ValidationHelper.isValidEmail(email); - }); - - const filteredOutEmailsCount = emailsBefore - emails.length; - - await slackPostMessage( - `Found ${emails.length} valid emails${filteredOutEmailsCount ? `. Filtered out ${filteredOutEmailsCount} invalid or demo emails` : ``}. Starting messaging`, - Constants.EXCEPTIONS_CHANNELS, - ); - - const batchSize = 10; - let allMailingResults = []; - - for (let i = 0; i < emails.length; i += batchSize) { - const emailsBatch = emails.slice(i, i + batchSize); - try { - const batchResults = await this.emailService.sendRemindersToUsers(emailsBatch); - allMailingResults = [...allMailingResults, ...batchResults]; - } catch (error) { - console.error(`Error processing batch ${Math.floor(i / batchSize) + 1}: ${error.message}`); - Sentry.captureException(error); - } - await new Promise((resolve) => setTimeout(resolve, 1000)); - } - - if (allMailingResults.length === 0) { - const mailingResultToString = 'Sending emails triggered, but no emails sent (no users found)'; - await slackPostMessage(mailingResultToString, Constants.EXCEPTIONS_CHANNELS); - await slackPostMessage(`morning cron finished at ${this.getCurrentTime()}`, Constants.EXCEPTIONS_CHANNELS); - } else { - await this.sendEmailResultsToSlack(allMailingResults, emails); - await slackPostMessage(`morning cron finished at ${this.getCurrentTime()}`, Constants.EXCEPTIONS_CHANNELS); - } - } catch (innerError) { - console.error('Detailed error in email processing:', innerError); - const errorMessage = innerError.stack - ? `${innerError.message}\n${innerError.stack.split('\n').slice(0, 5).join('\n')}` - : innerError.message; - await slackPostMessage(`Error in email processing: ${errorMessage}`, Constants.EXCEPTIONS_CHANNELS); - Sentry.captureException(innerError); - } - } catch (e) { - console.error('Main cron handler error:', e); - const errorMessage = e.stack ? `${e.message}\n${e.stack.split('\n').slice(0, 5).join('\n')}` : e.message; - await slackPostMessage(`Error in morning cron: ${errorMessage}`, Constants.EXCEPTIONS_CHANNELS); - Sentry.captureException(e); - } finally { - console.log('Cron job completed at', new Date().toISOString()); - } - } - - @Cron(CronExpression.EVERY_DAY_AT_NOON) - public async clearJobList(): Promise { - await this.jobListRepository.clear(); - } - - private async insertMidnightJob(): Promise { - return this.insertJobInProgress(Constants.MIDNIGHT_CRON_KEY); - } - - private async insertMorningJob(): Promise { - return this.insertJobInProgress(Constants.MORNING_CRON_KEY); - } - - private async insertJobInProgress(jobId: number): Promise { - try { - await this.jobListRepository.insert({ id: jobId }); - return true; - } catch (_error) { - return false; - } - } - - private emailCronResultToSlackString(results: Array): string | null { - try { - let output = '```\n'; - output += 'Idx | Accepted Email | Message ID\n'; - output += '----|---------------------------------|------------------------------------------\n'; - - results.forEach((result, idx) => { - const accepted = result.accepted && result.accepted.length > 0 ? result.accepted.join(', ') : '-'; - const messageId = result.messageId ?? '-'; - const idxStr = String(idx + 1).padEnd(3); - const acceptedStr = accepted.padEnd(32); - output += `${idxStr} | ${acceptedStr} | ${messageId}\n`; - }); - output += '```'; - return output; - } catch (_error) { - return null; - } - } - - private async sendEmailResultsToSlack( - results: Array, - allFoundEmails: Array, - ): Promise { - const filteredResults = results.filter((result) => !!result); - const nullResultsCount = results.length - filteredResults.length; - const chunkSize = 20; - - const foundEmails = new Set(); - filteredResults.forEach((result) => { - if (result?.accepted) { - result.accepted.forEach((email) => foundEmails.add(email)); - } - }); - - const emailsNonFoundInResults = allFoundEmails.filter((email) => !foundEmails.has(email)); - - for (let i = 0; i < filteredResults.length; i += chunkSize) { - const chunk = filteredResults.slice(i, i + chunkSize); - const message = this.emailCronResultToSlackString(chunk); - if (!message) { - continue; - } - await slackPostMessage(message, Constants.EXCEPTIONS_CHANNELS); - await new Promise((resolve) => setTimeout(resolve, 100)); - } - - if (nullResultsCount > 0) { - const timedOutMessage = `The system timed out while sending results to ${nullResultsCount} email addresses`; - if (emailsNonFoundInResults.length > 100) { - await slackPostMessage(timedOutMessage, Constants.EXCEPTIONS_CHANNELS); - for (let i = 0; i < emailsNonFoundInResults.length; i += 100) { - const emailsChunk = emailsNonFoundInResults.slice(i, i + 100); - await slackPostMessage( - `Failed emails (chunk ${i / 100 + 1}): ${emailsChunk.join(', ')}`, - Constants.EXCEPTIONS_CHANNELS, - ); - } - } else { - const timedOutEmailsMessage = `: \n${emailsNonFoundInResults.join(', ')}\n`; - const fullTimedOutMessage = `${timedOutMessage}${timedOutEmailsMessage}`; - await slackPostMessage(fullTimedOutMessage, Constants.EXCEPTIONS_CHANNELS); - } - } - } - - private getCurrentTime(): string { - return Constants.CURRENT_TIME_FORMATTED(); - } + constructor( + @Inject(UseCaseType.CHECK_USER_LOGS_AND_UPDATE_ACTIONS) + private readonly checkUsersLogsAndUpdateActionsUseCase: ICheckUsersLogsAndUpdateActionsUseCase, + @Inject(UseCaseType.CHECK_USER_ACTIONS_AND_MAIL_USERS) + private readonly checkUsersActionsAndMailingUsersUseCase: ICheckUsersActionsAndMailingUsers, + @InjectRepository(JobListEntity) + private readonly jobListRepository: Repository, + private readonly emailService: EmailService, + ) {} + + @Cron(CronExpression.EVERY_DAY_AT_MIDNIGHT) + async handleCron(): Promise { + try { + const isJobAdded = await this.insertMidnightJob(); + if (!isJobAdded) { + return; + } + await slackPostMessage(`midnight cron started at ${this.getCurrentTime()}`, Constants.EXCEPTIONS_CHANNELS); + await this.checkUsersLogsAndUpdateActionsUseCase.execute(); + await slackPostMessage(`midnight cron finished at ${this.getCurrentTime()}`, Constants.EXCEPTIONS_CHANNELS); + } catch (e) { + Sentry.captureException(e); + console.error(e); + } + } + + @Cron(CronExpression.EVERY_DAY_AT_8AM) + async handleMailingCron(): Promise { + try { + const isJobAdded = await this.insertMorningJob(); + if (!isJobAdded) { + console.log('Job already in progress, exiting'); + return; + } + + await slackPostMessage(`Email cron started at ${this.getCurrentTime()}`, Constants.EXCEPTIONS_CHANNELS); + + try { + let emails = await this.checkUsersActionsAndMailingUsersUseCase.execute(); + await slackPostMessage( + `Retrieved ${emails.length} email addresses from database`, + Constants.EXCEPTIONS_CHANNELS, + ); + + const emailsBefore = emails.length; + emails = emails.filter((email) => { + return ValidationHelper.isValidEmail(email); + }); + + const filteredOutEmailsCount = emailsBefore - emails.length; + + await slackPostMessage( + `Found ${emails.length} valid emails${filteredOutEmailsCount ? `. Filtered out ${filteredOutEmailsCount} invalid or demo emails` : ``}. Starting messaging`, + Constants.EXCEPTIONS_CHANNELS, + ); + + const batchSize = 10; + let allMailingResults = []; + + for (let i = 0; i < emails.length; i += batchSize) { + const emailsBatch = emails.slice(i, i + batchSize); + try { + const batchResults = await this.emailService.sendRemindersToUsers(emailsBatch); + allMailingResults = [...allMailingResults, ...batchResults]; + } catch (error) { + console.error(`Error processing batch ${Math.floor(i / batchSize) + 1}: ${error.message}`); + Sentry.captureException(error); + } + await new Promise((resolve) => setTimeout(resolve, 1000)); + } + + if (allMailingResults.length === 0) { + const mailingResultToString = 'Sending emails triggered, but no emails sent (no users found)'; + await slackPostMessage(mailingResultToString, Constants.EXCEPTIONS_CHANNELS); + await slackPostMessage(`morning cron finished at ${this.getCurrentTime()}`, Constants.EXCEPTIONS_CHANNELS); + } else { + await this.sendEmailResultsToSlack(allMailingResults, emails); + await slackPostMessage(`morning cron finished at ${this.getCurrentTime()}`, Constants.EXCEPTIONS_CHANNELS); + } + } catch (innerError) { + console.error('Detailed error in email processing:', innerError); + const errorMessage = innerError.stack + ? `${innerError.message}\n${innerError.stack.split('\n').slice(0, 5).join('\n')}` + : innerError.message; + await slackPostMessage(`Error in email processing: ${errorMessage}`, Constants.EXCEPTIONS_CHANNELS); + Sentry.captureException(innerError); + } + } catch (e) { + console.error('Main cron handler error:', e); + const errorMessage = e.stack ? `${e.message}\n${e.stack.split('\n').slice(0, 5).join('\n')}` : e.message; + await slackPostMessage(`Error in morning cron: ${errorMessage}`, Constants.EXCEPTIONS_CHANNELS); + Sentry.captureException(e); + } finally { + console.log('Cron job completed at', new Date().toISOString()); + } + } + + @Cron(CronExpression.EVERY_DAY_AT_NOON) + public async clearJobList(): Promise { + await this.jobListRepository.clear(); + } + + private async insertMidnightJob(): Promise { + return this.insertJobInProgress(Constants.MIDNIGHT_CRON_KEY); + } + + private async insertMorningJob(): Promise { + return this.insertJobInProgress(Constants.MORNING_CRON_KEY); + } + + private async insertJobInProgress(jobId: number): Promise { + try { + await this.jobListRepository.insert({ id: jobId }); + return true; + } catch (_error) { + return false; + } + } + + private emailCronResultToSlackString(results: Array): string | null { + try { + let output = '```\n'; + output += 'Idx | Accepted Email | Message ID\n'; + output += '----|---------------------------------|------------------------------------------\n'; + + results.forEach((result, idx) => { + const accepted = result.accepted && result.accepted.length > 0 ? result.accepted.join(', ') : '-'; + const messageId = result.messageId ?? '-'; + const idxStr = String(idx + 1).padEnd(3); + const acceptedStr = accepted.padEnd(32); + output += `${idxStr} | ${acceptedStr} | ${messageId}\n`; + }); + output += '```'; + return output; + } catch (_error) { + return null; + } + } + + private async sendEmailResultsToSlack( + results: Array, + allFoundEmails: Array, + ): Promise { + const filteredResults = results.filter((result) => !!result); + const nullResultsCount = results.length - filteredResults.length; + const chunkSize = 20; + + const foundEmails = new Set(); + filteredResults.forEach((result) => { + if (result?.accepted) { + result.accepted.forEach((email) => foundEmails.add(email)); + } + }); + + const emailsNonFoundInResults = allFoundEmails.filter((email) => !foundEmails.has(email)); + + for (let i = 0; i < filteredResults.length; i += chunkSize) { + const chunk = filteredResults.slice(i, i + chunkSize); + const message = this.emailCronResultToSlackString(chunk); + if (!message) { + continue; + } + await slackPostMessage(message, Constants.EXCEPTIONS_CHANNELS); + await new Promise((resolve) => setTimeout(resolve, 100)); + } + + if (nullResultsCount > 0) { + const timedOutMessage = `The system timed out while sending results to ${nullResultsCount} email addresses`; + if (emailsNonFoundInResults.length > 100) { + await slackPostMessage(timedOutMessage, Constants.EXCEPTIONS_CHANNELS); + for (let i = 0; i < emailsNonFoundInResults.length; i += 100) { + const emailsChunk = emailsNonFoundInResults.slice(i, i + 100); + await slackPostMessage( + `Failed emails (chunk ${i / 100 + 1}): ${emailsChunk.join(', ')}`, + Constants.EXCEPTIONS_CHANNELS, + ); + } + } else { + const timedOutEmailsMessage = `: \n${emailsNonFoundInResults.join(', ')}\n`; + const fullTimedOutMessage = `${timedOutMessage}${timedOutEmailsMessage}`; + await slackPostMessage(fullTimedOutMessage, Constants.EXCEPTIONS_CHANNELS); + } + } + } + + private getCurrentTime(): string { + return Constants.CURRENT_TIME_FORMATTED(); + } } diff --git a/backend/src/entities/cron-jobs/job-list.entity.ts b/backend/src/entities/cron-jobs/job-list.entity.ts index 4e815cc15..3fd87a62c 100644 --- a/backend/src/entities/cron-jobs/job-list.entity.ts +++ b/backend/src/entities/cron-jobs/job-list.entity.ts @@ -2,9 +2,9 @@ import { Column, Entity, PrimaryColumn } from 'typeorm'; @Entity('job_list') export class JobListEntity { - @PrimaryColumn({ type: 'int', nullable: false, unique: true }) - id: number; + @PrimaryColumn({ type: 'int', nullable: false, unique: true }) + id: number; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - createdAt: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + createdAt: Date; } diff --git a/backend/src/entities/custom-field/application/data-structures/create-custom-fields.ds.ts b/backend/src/entities/custom-field/application/data-structures/create-custom-fields.ds.ts index d604f5b3b..29e3d26d6 100644 --- a/backend/src/entities/custom-field/application/data-structures/create-custom-fields.ds.ts +++ b/backend/src/entities/custom-field/application/data-structures/create-custom-fields.ds.ts @@ -1,13 +1,13 @@ export class CreateCustomFieldsDs { - connectionId: string; - createFieldDto: CreateFieldDto; - masterPwd: string; - tableName: string; - userId: string; + connectionId: string; + createFieldDto: CreateFieldDto; + masterPwd: string; + tableName: string; + userId: string; } export class CreateFieldDto { - template_string: string; - text: string; - type: string; + template_string: string; + text: string; + type: string; } diff --git a/backend/src/entities/custom-field/application/data-structures/delete-custom-fields.ds.ts b/backend/src/entities/custom-field/application/data-structures/delete-custom-fields.ds.ts index 4af4b0f82..1413b04c1 100644 --- a/backend/src/entities/custom-field/application/data-structures/delete-custom-fields.ds.ts +++ b/backend/src/entities/custom-field/application/data-structures/delete-custom-fields.ds.ts @@ -1,5 +1,5 @@ export class DeleteCustomFieldsDs { - connectionId: string; - tableName: string; - fieldId: string; + connectionId: string; + tableName: string; + fieldId: string; } diff --git a/backend/src/entities/custom-field/application/data-structures/found-custom-fields.ds.ts b/backend/src/entities/custom-field/application/data-structures/found-custom-fields.ds.ts index 2f69dc0cc..3b83a48f8 100644 --- a/backend/src/entities/custom-field/application/data-structures/found-custom-fields.ds.ts +++ b/backend/src/entities/custom-field/application/data-structures/found-custom-fields.ds.ts @@ -1,15 +1,15 @@ import { ApiProperty } from '@nestjs/swagger'; export class FoundCustomFieldsDs { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - type: string; + @ApiProperty() + type: string; - @ApiProperty() - template_string: string; + @ApiProperty() + template_string: string; - @ApiProperty() - text: string; + @ApiProperty() + text: string; } diff --git a/backend/src/entities/custom-field/application/data-structures/get-custom-fields.ds.ts b/backend/src/entities/custom-field/application/data-structures/get-custom-fields.ds.ts index f2d75a249..f204793b5 100644 --- a/backend/src/entities/custom-field/application/data-structures/get-custom-fields.ds.ts +++ b/backend/src/entities/custom-field/application/data-structures/get-custom-fields.ds.ts @@ -1,4 +1,4 @@ export class GetCustomFieldsDs { - connectionId: string; - tableName: string; + connectionId: string; + tableName: string; } diff --git a/backend/src/entities/custom-field/application/data-structures/update-custom-fields.ds.ts b/backend/src/entities/custom-field/application/data-structures/update-custom-fields.ds.ts index 62034d03f..f391082c5 100644 --- a/backend/src/entities/custom-field/application/data-structures/update-custom-fields.ds.ts +++ b/backend/src/entities/custom-field/application/data-structures/update-custom-fields.ds.ts @@ -1,12 +1,12 @@ export class UpdateCustomFieldsDs { - connectionId: string; - masterPwd: string; - tableName: string; - updateFieldDto: { - id: string; - template_string: string; - text: string; - type: string; - }; - userId: string; + connectionId: string; + masterPwd: string; + tableName: string; + updateFieldDto: { + id: string; + template_string: string; + text: string; + type: string; + }; + userId: string; } diff --git a/backend/src/entities/custom-field/custom-field.controller.ts b/backend/src/entities/custom-field/custom-field.controller.ts index e5510cc31..5b5c1e7c6 100644 --- a/backend/src/entities/custom-field/custom-field.controller.ts +++ b/backend/src/entities/custom-field/custom-field.controller.ts @@ -16,6 +16,7 @@ import { HttpException } from '@nestjs/common/exceptions/http.exception.js'; import { ApiBearerAuth, ApiBody, ApiOperation, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger'; import { UseCaseType } from '../../common/data-injection.tokens.js'; import { MasterPassword, QueryTableName, QueryUuid, SlugUuid, UserId } from '../../decorators/index.js'; +import { Timeout } from '../../decorators/timeout.decorator.js'; import { InTransactionEnum } from '../../enums/index.js'; import { Messages } from '../../exceptions/text/messages.js'; import { ConnectionEditGuard, ConnectionReadGuard } from '../../guards/index.js'; @@ -33,7 +34,6 @@ import { IGetCustomFields, IUpdateCustomFields, } from './use-cases/custom-field-use-cases.interface.js'; -import { Timeout } from '../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/custom-field/custom-field.module.ts b/backend/src/entities/custom-field/custom-field.module.ts index 648af3e70..565f0149e 100644 --- a/backend/src/entities/custom-field/custom-field.module.ts +++ b/backend/src/entities/custom-field/custom-field.module.ts @@ -4,8 +4,8 @@ import { AuthMiddleware } from '../../authorization/index.js'; import { GlobalDatabaseContext } from '../../common/application/global-database-context.js'; import { BaseType, UseCaseType } from '../../common/data-injection.tokens.js'; import { AgentModule } from '../agent/agent.module.js'; -import { ConnectionPropertiesEntity } from '../connection-properties/connection-properties.entity.js'; import { ConnectionEntity } from '../connection/connection.entity.js'; +import { ConnectionPropertiesEntity } from '../connection-properties/connection-properties.entity.js'; import { GroupEntity } from '../group/group.entity.js'; import { LogOutEntity } from '../log-out/log-out.entity.js'; import { PermissionEntity } from '../permission/permission.entity.js'; @@ -22,56 +22,56 @@ import { GetCustomFieldsUseCase } from './use-cases/get-custom-fields.use.case.j import { UpdateCustomFieldUseCase } from './use-cases/update-custom-field.use.case.js'; @Module({ - imports: [ - TypeOrmModule.forFeature([ - ConnectionEntity, - CustomFieldsEntity, - GroupEntity, - PermissionEntity, - TableLogsEntity, - TableSettingsEntity, - TableWidgetEntity, - UserEntity, - ConnectionPropertiesEntity, - LogOutEntity, - ]), - AgentModule, - UserModule, - ], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.GET_CUSTOM_FIELDS, - useClass: GetCustomFieldsUseCase, - }, - { - provide: UseCaseType.CREATE_CUSTOM_FIELDS, - useClass: CreateCustomFieldsUseCase, - }, - { - provide: UseCaseType.UPDATE_CUSTOM_FIELDS, - useClass: UpdateCustomFieldUseCase, - }, - { - provide: UseCaseType.DELETE_CUSTOM_FIELD, - useClass: DeleteCustomFieldUseCase, - }, - ], - controllers: [CustomFieldController], - exports: [], + imports: [ + TypeOrmModule.forFeature([ + ConnectionEntity, + CustomFieldsEntity, + GroupEntity, + PermissionEntity, + TableLogsEntity, + TableSettingsEntity, + TableWidgetEntity, + UserEntity, + ConnectionPropertiesEntity, + LogOutEntity, + ]), + AgentModule, + UserModule, + ], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.GET_CUSTOM_FIELDS, + useClass: GetCustomFieldsUseCase, + }, + { + provide: UseCaseType.CREATE_CUSTOM_FIELDS, + useClass: CreateCustomFieldsUseCase, + }, + { + provide: UseCaseType.UPDATE_CUSTOM_FIELDS, + useClass: UpdateCustomFieldUseCase, + }, + { + provide: UseCaseType.DELETE_CUSTOM_FIELD, + useClass: DeleteCustomFieldUseCase, + }, + ], + controllers: [CustomFieldController], + exports: [], }) export class CustomFieldModule { - public configure(consumer: MiddlewareConsumer): any { - consumer - .apply(AuthMiddleware) - .forRoutes( - { path: '/fields/:connectionId', method: RequestMethod.GET }, - { path: '/field/:connectionId', method: RequestMethod.POST }, - { path: '/field/:connectionId', method: RequestMethod.PUT }, - { path: '/field/:connectionId', method: RequestMethod.DELETE }, - ); - } + public configure(consumer: MiddlewareConsumer): any { + consumer + .apply(AuthMiddleware) + .forRoutes( + { path: '/fields/:connectionId', method: RequestMethod.GET }, + { path: '/field/:connectionId', method: RequestMethod.POST }, + { path: '/field/:connectionId', method: RequestMethod.PUT }, + { path: '/field/:connectionId', method: RequestMethod.DELETE }, + ); + } } diff --git a/backend/src/entities/custom-field/custom-fields.entity.ts b/backend/src/entities/custom-field/custom-fields.entity.ts index 09f7742b5..56d9b8b55 100644 --- a/backend/src/entities/custom-field/custom-fields.entity.ts +++ b/backend/src/entities/custom-field/custom-fields.entity.ts @@ -3,19 +3,23 @@ import { TableSettingsEntity } from '../table-settings/common-table-settings/tab @Entity('customFields') export class CustomFieldsEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column() - type: string; + @Column() + type: string; - @Column() - template_string: string; + @Column() + template_string: string; - @Column() - text: string; + @Column() + text: string; - @ManyToOne(() => TableSettingsEntity, (settings) => settings.custom_fields, { onDelete: 'CASCADE' }) - @JoinColumn() - settings: Relation; + @ManyToOne( + () => TableSettingsEntity, + (settings) => settings.custom_fields, + { onDelete: 'CASCADE' }, + ) + @JoinColumn() + settings: Relation; } diff --git a/backend/src/entities/custom-field/dto/create-custom-field.dto.ts b/backend/src/entities/custom-field/dto/create-custom-field.dto.ts index 88e4b2139..2f81a6c95 100644 --- a/backend/src/entities/custom-field/dto/create-custom-field.dto.ts +++ b/backend/src/entities/custom-field/dto/create-custom-field.dto.ts @@ -2,22 +2,22 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsString, IsUUID } from 'class-validator'; export class CreateCustomFieldDto { - @ApiProperty() - @IsString() - type: string; + @ApiProperty() + @IsString() + type: string; - @ApiProperty() - @IsString() - text: string; + @ApiProperty() + @IsString() + text: string; - @ApiProperty() - @IsString() - template_string: string; + @ApiProperty() + @IsString() + template_string: string; } export class UpdateCustomFieldDTO extends CreateCustomFieldDto { - @IsString() - @IsUUID() - @ApiProperty() - id: string; + @IsString() + @IsUUID() + @ApiProperty() + id: string; } diff --git a/backend/src/entities/custom-field/repository/custom-field-repository-extension.ts b/backend/src/entities/custom-field/repository/custom-field-repository-extension.ts index 48b1ca8eb..d74380bce 100644 --- a/backend/src/entities/custom-field/repository/custom-field-repository-extension.ts +++ b/backend/src/entities/custom-field/repository/custom-field-repository-extension.ts @@ -2,31 +2,31 @@ import { TableSettingsEntity } from '../../table-settings/common-table-settings/ import { CustomFieldsEntity } from '../custom-fields.entity.js'; export const cusomFieldsCustomRepositoryExtension = { - async getCustomFields(connectionId: string, tableName: string): Promise> { - const qb = this.manager - .getRepository(TableSettingsEntity) - .createQueryBuilder('tableSettings') - .leftJoinAndSelect('tableSettings.custom_fields', 'custom_fields'); - qb.where('tableSettings.connection_id = :connection_id', { - connection_id: connectionId, - }); - qb.andWhere('tableSettings.table_name = :table_name', { - table_name: tableName, - }); - const result = await qb.getOne(); - return result?.custom_fields ? result.custom_fields : []; - }, + async getCustomFields(connectionId: string, tableName: string): Promise> { + const qb = this.manager + .getRepository(TableSettingsEntity) + .createQueryBuilder('tableSettings') + .leftJoinAndSelect('tableSettings.custom_fields', 'custom_fields'); + qb.where('tableSettings.connection_id = :connection_id', { + connection_id: connectionId, + }); + qb.andWhere('tableSettings.table_name = :table_name', { + table_name: tableName, + }); + const result = await qb.getOne(); + return result?.custom_fields ? result.custom_fields : []; + }, - async saveCustomFieldsEntity(customFields: CustomFieldsEntity): Promise { - return await this.save(customFields); - }, + async saveCustomFieldsEntity(customFields: CustomFieldsEntity): Promise { + return await this.save(customFields); + }, - async findCustomFieldById(customFieldId: string): Promise { - const qb = this.createQueryBuilder('customFields').where('customFields.id = :id', { id: customFieldId }); - return await qb.getOne(); - }, + async findCustomFieldById(customFieldId: string): Promise { + const qb = this.createQueryBuilder('customFields').where('customFields.id = :id', { id: customFieldId }); + return await qb.getOne(); + }, - async removeCustomFieldsEntity(customField: CustomFieldsEntity): Promise { - return await this.remove(customField); - }, + async removeCustomFieldsEntity(customField: CustomFieldsEntity): Promise { + return await this.remove(customField); + }, }; diff --git a/backend/src/entities/custom-field/repository/custom-fields-repository.interface.ts b/backend/src/entities/custom-field/repository/custom-fields-repository.interface.ts index c63a0c205..075193d3d 100644 --- a/backend/src/entities/custom-field/repository/custom-fields-repository.interface.ts +++ b/backend/src/entities/custom-field/repository/custom-fields-repository.interface.ts @@ -1,11 +1,11 @@ import { CustomFieldsEntity } from '../custom-fields.entity.js'; export interface ICustomFieldsRepository { - getCustomFields(connectionId: string, tableName: string): Promise>; + getCustomFields(connectionId: string, tableName: string): Promise>; - saveCustomFieldsEntity(customFields: CustomFieldsEntity): Promise; + saveCustomFieldsEntity(customFields: CustomFieldsEntity): Promise; - findCustomFieldById(customFieldId: string): Promise; + findCustomFieldById(customFieldId: string): Promise; - removeCustomFieldsEntity(customField: CustomFieldsEntity): Promise; + removeCustomFieldsEntity(customField: CustomFieldsEntity): Promise; } diff --git a/backend/src/entities/custom-field/use-cases/create-custom-fields.use.case.ts b/backend/src/entities/custom-field/use-cases/create-custom-fields.use.case.ts index 7ac06aace..bbf20d4a5 100644 --- a/backend/src/entities/custom-field/use-cases/create-custom-fields.use.case.ts +++ b/backend/src/entities/custom-field/use-cases/create-custom-fields.use.case.ts @@ -14,42 +14,41 @@ import { ICreateCustomFields } from './custom-field-use-cases.interface.js'; @Injectable() export class CreateCustomFieldsUseCase - extends AbstractUseCase - implements ICreateCustomFields + extends AbstractUseCase + implements ICreateCustomFields { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: CreateCustomFieldsDs): Promise { - const { connectionId, tableName, masterPwd, createFieldDto, userId } = inputData; - const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( - connectionId, - masterPwd, - ); - await validateCreateCustomFieldDto(createFieldDto, foundConnection, userId, tableName); - const foundTableSettingToUpdate: TableSettingsEntity = - await this._dbContext.tableSettingsRepository.findTableSettingsWithCustomFields(connectionId, tableName); - const newCustomFieldEntity = buildNewCustomFieldsEntity(inputData); - const savedCustomFields = await this._dbContext.customFieldsRepository.saveCustomFieldsEntity(newCustomFieldEntity); - if (foundTableSettingToUpdate) { - if (Array.isArray(foundTableSettingToUpdate.custom_fields)) { - foundTableSettingToUpdate.custom_fields.push(savedCustomFields); - } else { - foundTableSettingToUpdate.custom_fields = [savedCustomFields]; - } - const savedSettings = await this._dbContext.tableSettingsRepository.saveNewOrUpdatedSettings( - foundTableSettingToUpdate, - ); - return buildFoundTableSettingsDs(savedSettings); - } - const emptyTableSettings: CreateTableSettingsDs = buildEmptyTableSettings(connectionId, tableName); - const savedTableSettings = await this._dbContext.tableSettingsRepository.createNewTableSettings(emptyTableSettings); - savedTableSettings.custom_fields = [savedCustomFields]; - const savedSettings = await this._dbContext.tableSettingsRepository.saveNewOrUpdatedSettings(savedTableSettings); - return buildFoundTableSettingsDs(savedSettings); - } + protected async implementation(inputData: CreateCustomFieldsDs): Promise { + const { connectionId, tableName, masterPwd, createFieldDto, userId } = inputData; + const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( + connectionId, + masterPwd, + ); + await validateCreateCustomFieldDto(createFieldDto, foundConnection, userId, tableName); + const foundTableSettingToUpdate: TableSettingsEntity = + await this._dbContext.tableSettingsRepository.findTableSettingsWithCustomFields(connectionId, tableName); + const newCustomFieldEntity = buildNewCustomFieldsEntity(inputData); + const savedCustomFields = await this._dbContext.customFieldsRepository.saveCustomFieldsEntity(newCustomFieldEntity); + if (foundTableSettingToUpdate) { + if (Array.isArray(foundTableSettingToUpdate.custom_fields)) { + foundTableSettingToUpdate.custom_fields.push(savedCustomFields); + } else { + foundTableSettingToUpdate.custom_fields = [savedCustomFields]; + } + const savedSettings = + await this._dbContext.tableSettingsRepository.saveNewOrUpdatedSettings(foundTableSettingToUpdate); + return buildFoundTableSettingsDs(savedSettings); + } + const emptyTableSettings: CreateTableSettingsDs = buildEmptyTableSettings(connectionId, tableName); + const savedTableSettings = await this._dbContext.tableSettingsRepository.createNewTableSettings(emptyTableSettings); + savedTableSettings.custom_fields = [savedCustomFields]; + const savedSettings = await this._dbContext.tableSettingsRepository.saveNewOrUpdatedSettings(savedTableSettings); + return buildFoundTableSettingsDs(savedSettings); + } } diff --git a/backend/src/entities/custom-field/use-cases/custom-field-use-cases.interface.ts b/backend/src/entities/custom-field/use-cases/custom-field-use-cases.interface.ts index e6c1d33c4..74c64210b 100644 --- a/backend/src/entities/custom-field/use-cases/custom-field-use-cases.interface.ts +++ b/backend/src/entities/custom-field/use-cases/custom-field-use-cases.interface.ts @@ -7,17 +7,17 @@ import { GetCustomFieldsDs } from '../application/data-structures/get-custom-fie import { UpdateCustomFieldsDs } from '../application/data-structures/update-custom-fields.ds.js'; export interface IGetCustomFields { - execute(inputData: GetCustomFieldsDs, inTransaction: InTransactionEnum): Promise>; + execute(inputData: GetCustomFieldsDs, inTransaction: InTransactionEnum): Promise>; } export interface ICreateCustomFields { - execute(inputData: CreateCustomFieldsDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: CreateCustomFieldsDs, inTransaction: InTransactionEnum): Promise; } export interface IUpdateCustomFields { - execute(inputData: UpdateCustomFieldsDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: UpdateCustomFieldsDs, inTransaction: InTransactionEnum): Promise; } export interface IDeleteCustomField { - execute(inputData: DeleteCustomFieldsDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: DeleteCustomFieldsDs, inTransaction: InTransactionEnum): Promise; } diff --git a/backend/src/entities/custom-field/use-cases/delete-custom-field.use.case.ts b/backend/src/entities/custom-field/use-cases/delete-custom-field.use.case.ts index dec3bf15b..ab4192833 100644 --- a/backend/src/entities/custom-field/use-cases/delete-custom-field.use.case.ts +++ b/backend/src/entities/custom-field/use-cases/delete-custom-field.use.case.ts @@ -11,44 +11,44 @@ import { IDeleteCustomField } from './custom-field-use-cases.interface.js'; @Injectable() export class DeleteCustomFieldUseCase - extends AbstractUseCase - implements IDeleteCustomField + extends AbstractUseCase + implements IDeleteCustomField { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: DeleteCustomFieldsDs): Promise { - const { connectionId, tableName, fieldId } = inputData; - const fieldToDelete = await this._dbContext.customFieldsRepository.findCustomFieldById(fieldId); - if (!fieldToDelete) { - throw new HttpException( - { - message: Messages.CUSTOM_FIELD_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - const tableSettingsToUpdate = await this._dbContext.tableSettingsRepository.findTableSettingsWithCustomFields( - connectionId, - tableName, - ); - if (!tableSettingsToUpdate) { - throw new HttpException( - { - message: Messages.TABLE_SETTINGS_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - const delIndex = tableSettingsToUpdate.custom_fields.findIndex((field) => field.id === fieldId); - tableSettingsToUpdate.custom_fields.splice(delIndex, 1); - await this._dbContext.customFieldsRepository.removeCustomFieldsEntity(fieldToDelete); - const updatedTableSettings = - await this._dbContext.tableSettingsRepository.saveNewOrUpdatedSettings(tableSettingsToUpdate); - return buildFoundTableSettingsDs(updatedTableSettings); - } + protected async implementation(inputData: DeleteCustomFieldsDs): Promise { + const { connectionId, tableName, fieldId } = inputData; + const fieldToDelete = await this._dbContext.customFieldsRepository.findCustomFieldById(fieldId); + if (!fieldToDelete) { + throw new HttpException( + { + message: Messages.CUSTOM_FIELD_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + const tableSettingsToUpdate = await this._dbContext.tableSettingsRepository.findTableSettingsWithCustomFields( + connectionId, + tableName, + ); + if (!tableSettingsToUpdate) { + throw new HttpException( + { + message: Messages.TABLE_SETTINGS_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + const delIndex = tableSettingsToUpdate.custom_fields.findIndex((field) => field.id === fieldId); + tableSettingsToUpdate.custom_fields.splice(delIndex, 1); + await this._dbContext.customFieldsRepository.removeCustomFieldsEntity(fieldToDelete); + const updatedTableSettings = + await this._dbContext.tableSettingsRepository.saveNewOrUpdatedSettings(tableSettingsToUpdate); + return buildFoundTableSettingsDs(updatedTableSettings); + } } diff --git a/backend/src/entities/custom-field/use-cases/get-custom-fields.use.case.ts b/backend/src/entities/custom-field/use-cases/get-custom-fields.use.case.ts index c70b85a9d..468549b05 100644 --- a/backend/src/entities/custom-field/use-cases/get-custom-fields.use.case.ts +++ b/backend/src/entities/custom-field/use-cases/get-custom-fields.use.case.ts @@ -10,24 +10,24 @@ import { IGetCustomFields } from './custom-field-use-cases.interface.js'; @Injectable() export class GetCustomFieldsUseCase - extends AbstractUseCase> - implements IGetCustomFields + extends AbstractUseCase> + implements IGetCustomFields { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: GetCustomFieldsDs): Promise> { - const { connectionId, tableName } = inputData; - const foundCustomFields = await this._dbContext.customFieldsRepository.getCustomFields(connectionId, tableName); - if (foundCustomFields.length <= 0) { - return []; - } - return foundCustomFields.map((field: CustomFieldsEntity) => { - return buildFoundCustomFieldsDs(field); - }); - } + protected async implementation(inputData: GetCustomFieldsDs): Promise> { + const { connectionId, tableName } = inputData; + const foundCustomFields = await this._dbContext.customFieldsRepository.getCustomFields(connectionId, tableName); + if (foundCustomFields.length <= 0) { + return []; + } + return foundCustomFields.map((field: CustomFieldsEntity) => { + return buildFoundCustomFieldsDs(field); + }); + } } diff --git a/backend/src/entities/custom-field/use-cases/update-custom-field.use.case.ts b/backend/src/entities/custom-field/use-cases/update-custom-field.use.case.ts index 89eb32ca4..f081a3b0c 100644 --- a/backend/src/entities/custom-field/use-cases/update-custom-field.use.case.ts +++ b/backend/src/entities/custom-field/use-cases/update-custom-field.use.case.ts @@ -12,36 +12,36 @@ import { IUpdateCustomFields } from './custom-field-use-cases.interface.js'; @Injectable() export class UpdateCustomFieldUseCase - extends AbstractUseCase - implements IUpdateCustomFields + extends AbstractUseCase + implements IUpdateCustomFields { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: UpdateCustomFieldsDs): Promise { - const updateFieldDto = inputData.updateFieldDto; - const { connectionId, tableName, masterPwd, userId } = inputData; - const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( - connectionId, - masterPwd, - ); - await validateCreateCustomFieldDto(updateFieldDto, foundConnection, userId, tableName); - const fieldToUpdate = await this._dbContext.customFieldsRepository.findCustomFieldById(updateFieldDto.id); - if (!fieldToUpdate) { - throw new HttpException( - { - message: Messages.CUSTOM_FIELD_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - delete updateFieldDto.id; - const updated = Object.assign(fieldToUpdate, updateFieldDto); - const updatedCustomFields = await this._dbContext.customFieldsRepository.saveCustomFieldsEntity(updated); - return buildFoundCustomFieldsDs(updatedCustomFields); - } + protected async implementation(inputData: UpdateCustomFieldsDs): Promise { + const updateFieldDto = inputData.updateFieldDto; + const { connectionId, tableName, masterPwd, userId } = inputData; + const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( + connectionId, + masterPwd, + ); + await validateCreateCustomFieldDto(updateFieldDto, foundConnection, userId, tableName); + const fieldToUpdate = await this._dbContext.customFieldsRepository.findCustomFieldById(updateFieldDto.id); + if (!fieldToUpdate) { + throw new HttpException( + { + message: Messages.CUSTOM_FIELD_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + delete updateFieldDto.id; + const updated = Object.assign(fieldToUpdate, updateFieldDto); + const updatedCustomFields = await this._dbContext.customFieldsRepository.saveCustomFieldsEntity(updated); + return buildFoundCustomFieldsDs(updatedCustomFields); + } } diff --git a/backend/src/entities/custom-field/utils/build-found-custom-fields-ds.ts b/backend/src/entities/custom-field/utils/build-found-custom-fields-ds.ts index bbdb81eac..29704bc35 100644 --- a/backend/src/entities/custom-field/utils/build-found-custom-fields-ds.ts +++ b/backend/src/entities/custom-field/utils/build-found-custom-fields-ds.ts @@ -1,12 +1,12 @@ -import { CustomFieldsEntity } from '../custom-fields.entity.js'; import { FoundCustomFieldsDs } from '../application/data-structures/found-custom-fields.ds.js'; +import { CustomFieldsEntity } from '../custom-fields.entity.js'; export function buildFoundCustomFieldsDs(customField: CustomFieldsEntity): FoundCustomFieldsDs { - const { id, template_string, text, type } = customField; - return { - id: id, - template_string: template_string, - text: text, - type: type, - }; + const { id, template_string, text, type } = customField; + return { + id: id, + template_string: template_string, + text: text, + type: type, + }; } diff --git a/backend/src/entities/custom-field/utils/build-new-custom-fields-entity.ts b/backend/src/entities/custom-field/utils/build-new-custom-fields-entity.ts index 758b5ce6e..1213a19b1 100644 --- a/backend/src/entities/custom-field/utils/build-new-custom-fields-entity.ts +++ b/backend/src/entities/custom-field/utils/build-new-custom-fields-entity.ts @@ -2,12 +2,12 @@ import { CreateCustomFieldsDs } from '../application/data-structures/create-cust import { CustomFieldsEntity } from '../custom-fields.entity.js'; export function buildNewCustomFieldsEntity(inputData: CreateCustomFieldsDs): CustomFieldsEntity { - const { - createFieldDto: { template_string, text, type }, - } = inputData; - const newCustomField = new CustomFieldsEntity(); - newCustomField.template_string = template_string; - newCustomField.text = text; - newCustomField.type = type; - return newCustomField; + const { + createFieldDto: { template_string, text, type }, + } = inputData; + const newCustomField = new CustomFieldsEntity(); + newCustomField.template_string = template_string; + newCustomField.text = text; + newCustomField.type = type; + return newCustomField; } diff --git a/backend/src/entities/custom-field/utils/validate-create-custom-field-dto.ts b/backend/src/entities/custom-field/utils/validate-create-custom-field-dto.ts index 1f6703942..6b518f0f0 100644 --- a/backend/src/entities/custom-field/utils/validate-create-custom-field-dto.ts +++ b/backend/src/entities/custom-field/utils/validate-create-custom-field-dto.ts @@ -1,49 +1,49 @@ -import { CreateFieldDto } from '../application/data-structures/create-custom-fields.ds.js'; -import { ConnectionEntity } from '../../connection/connection.entity.js'; -import { Messages } from '../../../exceptions/text/messages.js'; -import { getValuesBetweenCurlies, toPrettyErrorsMsg } from '../../../helpers/index.js'; -import { HttpException } from '@nestjs/common/exceptions/http.exception.js'; import { HttpStatus } from '@nestjs/common'; +import { HttpException } from '@nestjs/common/exceptions/http.exception.js'; import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; +import { Messages } from '../../../exceptions/text/messages.js'; +import { getValuesBetweenCurlies, toPrettyErrorsMsg } from '../../../helpers/index.js'; +import { ConnectionEntity } from '../../connection/connection.entity.js'; +import { CreateFieldDto } from '../application/data-structures/create-custom-fields.ds.js'; export async function validateCreateCustomFieldDto( - createFieldDto: CreateFieldDto, - connection: ConnectionEntity, - _userId: string, - tableName: string, + createFieldDto: CreateFieldDto, + connection: ConnectionEntity, + _userId: string, + tableName: string, ): Promise { - const errors = []; - const { template_string, text, type } = createFieldDto; - if (!type) errors.push(Messages.CUSTOM_FIELD_TYPE_MISSING); - if (!text) errors.push(Messages.CUSTOM_FIELD_TEXT_MISSING); - if (!template_string) errors.push(Messages.CUSTOM_FIELD_TEMPLATE_MISSING); - if (type && type !== 'AA:Link') errors.push(Messages.CUSTOM_FIELD_TYPE_INCORRECT); - const tableFieldsFromTemplate = getValuesBetweenCurlies(template_string); - const dao = getDataAccessObject(connection); - const tablesInConnection: Array = (await dao.getTablesFromDB()).map((table) => table.tableName); - const tableIndexInTables = tablesInConnection.indexOf(tableName); - if (tableIndexInTables < 0) { - throw new HttpException( - { - message: Messages.TABLE_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - const tableStructure = await dao.getTableStructure(tableName, undefined); - const tableColumns = tableStructure.map((el) => el.column_name); - for (const field of tableFieldsFromTemplate) { - const fieldIndex = tableColumns.indexOf(field); - if (fieldIndex < 0) { - errors.push(Messages.EXCLUDED_OR_NOT_EXISTS(field)); - } - } - if (errors.length > 0) { - throw new HttpException( - { - message: toPrettyErrorsMsg(errors), - }, - HttpStatus.BAD_REQUEST, - ); - } + const errors = []; + const { template_string, text, type } = createFieldDto; + if (!type) errors.push(Messages.CUSTOM_FIELD_TYPE_MISSING); + if (!text) errors.push(Messages.CUSTOM_FIELD_TEXT_MISSING); + if (!template_string) errors.push(Messages.CUSTOM_FIELD_TEMPLATE_MISSING); + if (type && type !== 'AA:Link') errors.push(Messages.CUSTOM_FIELD_TYPE_INCORRECT); + const tableFieldsFromTemplate = getValuesBetweenCurlies(template_string); + const dao = getDataAccessObject(connection); + const tablesInConnection: Array = (await dao.getTablesFromDB()).map((table) => table.tableName); + const tableIndexInTables = tablesInConnection.indexOf(tableName); + if (tableIndexInTables < 0) { + throw new HttpException( + { + message: Messages.TABLE_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + const tableStructure = await dao.getTableStructure(tableName, undefined); + const tableColumns = tableStructure.map((el) => el.column_name); + for (const field of tableFieldsFromTemplate) { + const fieldIndex = tableColumns.indexOf(field); + if (fieldIndex < 0) { + errors.push(Messages.EXCLUDED_OR_NOT_EXISTS(field)); + } + } + if (errors.length > 0) { + throw new HttpException( + { + message: toPrettyErrorsMsg(errors), + }, + HttpStatus.BAD_REQUEST, + ); + } } diff --git a/backend/src/entities/demo-data/demo-data.service.ts b/backend/src/entities/demo-data/demo-data.service.ts index 83ab1f421..85f37271d 100644 --- a/backend/src/entities/demo-data/demo-data.service.ts +++ b/backend/src/entities/demo-data/demo-data.service.ts @@ -8,16 +8,16 @@ import { TableActionTypeEnum } from '../../enums/table-action-type.enum.js'; import { isTest } from '../../helpers/app/is-test.js'; import { Constants } from '../../helpers/constants/constants.js'; import { slackPostMessage } from '../../helpers/index.js'; +import { ConnectionEntity } from '../connection/connection.entity.js'; import { CreateConnectionPropertiesDs } from '../connection-properties/application/data-structures/create-connection-properties.ds.js'; import { ConnectionPropertiesEntity } from '../connection-properties/connection-properties.entity.js'; import { buildConnectionPropertiesEntity } from '../connection-properties/utils/build-connection-properties-entity.js'; -import { ConnectionEntity } from '../connection/connection.entity.js'; import { GroupEntity } from '../group/group.entity.js'; import { PermissionEntity } from '../permission/permission.entity.js'; import { buildActionEventWithRule } from '../table-actions/table-action-events-module/utils/build-action-event-with-rule.util.js'; import { - CreateRuleDataDs, - CreateTableActionEventDS, + CreateRuleDataDs, + CreateTableActionEventDS, } from '../table-actions/table-action-rules-module/application/data-structures/create-action-rules.ds.js'; import { buildEmptyActionRule } from '../table-actions/table-action-rules-module/utils/build-empty-action-rule.util.js'; import { CreateTableFilterDs } from '../table-filters/application/data-structures/create-table-filters.ds.js'; @@ -33,1189 +33,1189 @@ import { buildNewTableWidgetEntity } from '../widget/utils/build-new-table-widge @Injectable() export class DemoDataService { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) {} + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) {} - public async createDemoDataForUser(userId: string): Promise> { - try { - return await this.createDemoData(userId); - } catch (error) { - console.error(`Error during demo data creation for user with ID ${userId}:`, error); - await slackPostMessage(`Error during demo data creation for user with ID ${userId}: ${error.message}`); - } - } + public async createDemoDataForUser(userId: string): Promise> { + try { + return await this.createDemoData(userId); + } catch (error) { + console.error(`Error during demo data creation for user with ID ${userId}:`, error); + await slackPostMessage(`Error during demo data creation for user with ID ${userId}: ${error.message}`); + } + } - private async createDemoData(userId: string): Promise> { - const foundUser = await this._dbContext.userRepository.findOne({ - where: { id: userId }, - }); + private async createDemoData(userId: string): Promise> { + const foundUser = await this._dbContext.userRepository.findOne({ + where: { id: userId }, + }); - if (!foundUser) { - throw new Error(`Unexpected error in demo data creation: User with ID ${userId} not found.`); - } + if (!foundUser) { + throw new Error(`Unexpected error in demo data creation: User with ID ${userId} not found.`); + } - const testConnections = Constants.getTestConnectionsArr(); - const testConnectionsEntities = buildConnectionEntitiesFromTestDtos(testConnections); - const createdTestConnections = await Promise.all( - testConnectionsEntities.map(async (connection): Promise => { - connection.author = foundUser; - return await this._dbContext.connectionRepository.saveNewConnection(connection); - }), - ); - const testGroupsEntities = buildDefaultAdminGroups(foundUser, createdTestConnections); - const createdTestGroups = await Promise.all( - testGroupsEntities.map(async (group: GroupEntity) => { - return await this._dbContext.groupRepository.saveNewOrUpdatedGroup(group); - }), - ); - const testPermissionsEntities = buildDefaultAdminPermissions(createdTestGroups); - await Promise.all( - testPermissionsEntities.map(async (permission: PermissionEntity) => { - await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(permission); - }), - ); + const testConnections = Constants.getTestConnectionsArr(); + const testConnectionsEntities = buildConnectionEntitiesFromTestDtos(testConnections); + const createdTestConnections = await Promise.all( + testConnectionsEntities.map(async (connection): Promise => { + connection.author = foundUser; + return await this._dbContext.connectionRepository.saveNewConnection(connection); + }), + ); + const testGroupsEntities = buildDefaultAdminGroups(foundUser, createdTestConnections); + const createdTestGroups = await Promise.all( + testGroupsEntities.map(async (group: GroupEntity) => { + return await this._dbContext.groupRepository.saveNewOrUpdatedGroup(group); + }), + ); + const testPermissionsEntities = buildDefaultAdminPermissions(createdTestGroups); + await Promise.all( + testPermissionsEntities.map(async (permission: PermissionEntity) => { + await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(permission); + }), + ); - if (!isTest()) { - const createdPostgresConnection = createdTestConnections.find( - (connection) => connection.type === ConnectionTypesEnum.postgres, - ); - if (createdPostgresConnection) { - await this.createTestTableSettingsPostgres(createdPostgresConnection); - await this.createConnectionPropertiesForPostgresDemoData(createdPostgresConnection); - await this.createPostgresDemoTableActions(createdPostgresConnection); - await this.createDemoPostgresSavedTableFilters(createdPostgresConnection); - } - const createdMySQLConnection = createdTestConnections.find( - (connection) => connection.type === ConnectionTypesEnum.mysql || connection.type === ConnectionTypesEnum.mysql2, - ); - if (createdMySQLConnection) { - await this.createTestTableSettingsMySQL(createdMySQLConnection); - await this.createConnectionPropertiesForMySQLDemoData(createdMySQLConnection); - await this.createMySQLDemoTableActions(createdMySQLConnection); - await this.createMySQLPostgresSavedTableFilters(createdMySQLConnection); - } - } + if (!isTest()) { + const createdPostgresConnection = createdTestConnections.find( + (connection) => connection.type === ConnectionTypesEnum.postgres, + ); + if (createdPostgresConnection) { + await this.createTestTableSettingsPostgres(createdPostgresConnection); + await this.createConnectionPropertiesForPostgresDemoData(createdPostgresConnection); + await this.createPostgresDemoTableActions(createdPostgresConnection); + await this.createDemoPostgresSavedTableFilters(createdPostgresConnection); + } + const createdMySQLConnection = createdTestConnections.find( + (connection) => connection.type === ConnectionTypesEnum.mysql || connection.type === ConnectionTypesEnum.mysql2, + ); + if (createdMySQLConnection) { + await this.createTestTableSettingsMySQL(createdMySQLConnection); + await this.createConnectionPropertiesForMySQLDemoData(createdMySQLConnection); + await this.createMySQLDemoTableActions(createdMySQLConnection); + await this.createMySQLPostgresSavedTableFilters(createdMySQLConnection); + } + } - return createdTestConnections; - } + return createdTestConnections; + } - private async createTestTableSettingsMySQL(connection: ConnectionEntity): Promise> { - const tableSettingsDtos: Array = [ - { - table_name: 'event', - display_name: '', - search_fields: [], - excluded_fields: [], - readonly_fields: [], - sortable_by: [], - autocomplete_columns: ['title', 'description'], - identification_fields: [], - identity_column: 'title', - can_delete: true, - can_update: true, - can_add: true, - sensitive_fields: [], - icon: 'celebration', - allow_csv_export: true, - allow_csv_import: true, - connection_id: connection.id, - masterPwd: null, - userId: connection?.author?.id || null, - }, - { - table_name: 'event_attendee', - display_name: '', - search_fields: ['event_id', 'user_id', 'guest_name', 'guest_email', 'status'], - excluded_fields: [], - readonly_fields: [], - sortable_by: [], - autocomplete_columns: ['event_id', 'user_id', 'guest_name', 'guest_email'], - identification_fields: [], - identity_column: 'user_id', - can_delete: true, - can_update: true, - can_add: true, - sensitive_fields: [], - icon: 'groups', - allow_csv_export: true, - allow_csv_import: true, - connection_id: connection.id, - masterPwd: null, - userId: connection?.author?.id || null, - }, - { - table_name: 'events', - display_name: null, - search_fields: [], - excluded_fields: [], - readonly_fields: [], - sortable_by: [], - autocomplete_columns: [], - identification_fields: [], - identity_column: null, - can_delete: true, - can_update: true, - can_add: true, - sensitive_fields: null, - icon: null, - allow_csv_export: true, - allow_csv_import: true, - connection_id: connection.id, - masterPwd: null, - userId: connection?.author?.id || null, - }, - { - table_name: 'location', - display_name: '', - search_fields: ['name', 'address', 'city', 'country'], - excluded_fields: [], - readonly_fields: [], - sortable_by: [], - autocomplete_columns: ['name', 'address', 'city', 'country'], - identification_fields: [], - identity_column: 'name', - can_delete: true, - can_update: true, - can_add: true, - sensitive_fields: [], - icon: 'domain', - allow_csv_export: true, - allow_csv_import: true, - connection_id: connection.id, - masterPwd: null, - userId: connection?.author?.id || null, - }, - { - table_name: 'membership', - display_name: '', - search_fields: ['user_id', 'space_id', 'membership_type'], - excluded_fields: [], - readonly_fields: [], - sortable_by: [], - autocomplete_columns: ['user_id', 'space_id'], - identification_fields: [], - identity_column: 'user_id', - can_delete: true, - can_update: true, - can_add: true, - sensitive_fields: [], - icon: 'diamond', - allow_csv_export: true, - allow_csv_import: true, - connection_id: connection.id, - masterPwd: null, - userId: connection?.author?.id || null, - }, - { - table_name: 'space', - display_name: '', - search_fields: ['location_id', 'name', 'type', 'description'], - excluded_fields: [], - readonly_fields: [], - sortable_by: [], - autocomplete_columns: ['location_id', 'name', 'description'], - identification_fields: [], - identity_column: 'name', - can_delete: true, - can_update: true, - can_add: true, - sensitive_fields: [], - icon: 'desk', - allow_csv_export: true, - allow_csv_import: true, - connection_id: connection.id, - masterPwd: null, - userId: connection?.author?.id || null, - }, - { - table_name: 'table-1', - display_name: '', - search_fields: [], - excluded_fields: [], - readonly_fields: [], - sortable_by: [], - autocomplete_columns: [], - identification_fields: [], - identity_column: '', - can_delete: true, - can_update: true, - can_add: true, - sensitive_fields: [], - icon: '', - allow_csv_export: true, - allow_csv_import: true, - connection_id: connection.id, - masterPwd: null, - userId: connection?.author?.id || null, - }, - { - table_name: 'user', - display_name: '', - search_fields: ['name', 'email', 'phone'], - excluded_fields: [], - readonly_fields: [], - sortable_by: [], - autocomplete_columns: ['name', 'email', 'phone'], - identification_fields: [], - identity_column: 'name', - can_delete: true, - can_update: true, - can_add: true, - sensitive_fields: ['email', 'phone'], - icon: 'person', - allow_csv_export: true, - allow_csv_import: true, - connection_id: connection.id, - masterPwd: null, - userId: connection?.author?.id || null, - }, - ]; - const tableSettingEntities = tableSettingsDtos.map((dto) => { - return buildNewTableSettingsEntity(dto, connection); - }); - const savedTableSettings = await this._dbContext.tableSettingsRepository.save(tableSettingEntities); - await this.createDemoMySQLTablesWidgets(savedTableSettings); - return savedTableSettings; - } + private async createTestTableSettingsMySQL(connection: ConnectionEntity): Promise> { + const tableSettingsDtos: Array = [ + { + table_name: 'event', + display_name: '', + search_fields: [], + excluded_fields: [], + readonly_fields: [], + sortable_by: [], + autocomplete_columns: ['title', 'description'], + identification_fields: [], + identity_column: 'title', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: 'celebration', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'event_attendee', + display_name: '', + search_fields: ['event_id', 'user_id', 'guest_name', 'guest_email', 'status'], + excluded_fields: [], + readonly_fields: [], + sortable_by: [], + autocomplete_columns: ['event_id', 'user_id', 'guest_name', 'guest_email'], + identification_fields: [], + identity_column: 'user_id', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: 'groups', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'events', + display_name: null, + search_fields: [], + excluded_fields: [], + readonly_fields: [], + sortable_by: [], + autocomplete_columns: [], + identification_fields: [], + identity_column: null, + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: null, + icon: null, + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'location', + display_name: '', + search_fields: ['name', 'address', 'city', 'country'], + excluded_fields: [], + readonly_fields: [], + sortable_by: [], + autocomplete_columns: ['name', 'address', 'city', 'country'], + identification_fields: [], + identity_column: 'name', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: 'domain', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'membership', + display_name: '', + search_fields: ['user_id', 'space_id', 'membership_type'], + excluded_fields: [], + readonly_fields: [], + sortable_by: [], + autocomplete_columns: ['user_id', 'space_id'], + identification_fields: [], + identity_column: 'user_id', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: 'diamond', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'space', + display_name: '', + search_fields: ['location_id', 'name', 'type', 'description'], + excluded_fields: [], + readonly_fields: [], + sortable_by: [], + autocomplete_columns: ['location_id', 'name', 'description'], + identification_fields: [], + identity_column: 'name', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: 'desk', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'table-1', + display_name: '', + search_fields: [], + excluded_fields: [], + readonly_fields: [], + sortable_by: [], + autocomplete_columns: [], + identification_fields: [], + identity_column: '', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: '', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'user', + display_name: '', + search_fields: ['name', 'email', 'phone'], + excluded_fields: [], + readonly_fields: [], + sortable_by: [], + autocomplete_columns: ['name', 'email', 'phone'], + identification_fields: [], + identity_column: 'name', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: ['email', 'phone'], + icon: 'person', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + ]; + const tableSettingEntities = tableSettingsDtos.map((dto) => { + return buildNewTableSettingsEntity(dto, connection); + }); + const savedTableSettings = await this._dbContext.tableSettingsRepository.save(tableSettingEntities); + await this.createDemoMySQLTablesWidgets(savedTableSettings); + return savedTableSettings; + } - private async createDemoMySQLTablesWidgets(tableSettings: Array): Promise { - const foundEventTableSettings = tableSettings.find((settings) => settings.table_name === 'event'); - if (foundEventTableSettings) { - const createEventWidgetsData: Array = [ - { - field_name: 'organizer_id', - widget_type: '' as any, - name: 'Organizer', - description: '', - widget_params: null, - widget_options: null, - }, - { - field_name: 'space_id', - widget_type: '' as any, - name: 'Space', - description: '', - widget_params: null, - widget_options: null, - }, - { - field_name: 'start_time', - widget_type: '' as any, - name: 'Starts at', - description: '', - widget_params: null, - widget_options: null, - }, - { - field_name: 'end_time', - widget_type: '' as any, - name: 'Ends at', - description: '', - widget_params: null, - widget_options: null, - }, - { - field_name: 'title', - widget_type: '' as any, - name: 'Event name', - description: '', - widget_params: null, - widget_options: null, - }, - { - field_name: 'image_url', - widget_type: 'Image' as any, - name: 'Poster', - description: '', - widget_params: - '// provide image height in px to dispaly in table\n// prefix: optional URL prefix to prepend to image source\n// example:\n{\n "height": 100,\n "prefix": "https://demo-data.rocketadmin.com/mysql-demo-images/"\n}\n', - widget_options: null, - }, - ]; - const newWidgets = createEventWidgetsData.map((widget) => { - const newWidget = buildNewTableWidgetEntity(widget); - newWidget.settings = foundEventTableSettings; - return newWidget; - }); - await this._dbContext.tableWidgetsRepository.save(newWidgets); - } - const foundEventAttendeeTableSettings = tableSettings.find((settings) => settings.table_name === 'event_attendee'); - if (foundEventAttendeeTableSettings) { - const createEventAttendeeWidgetsData: Array = [ - { - field_name: 'event_id', - widget_type: '' as any, - name: 'Event', - description: '', - widget_params: null, - widget_options: null, - }, - { - field_name: 'user_id', - widget_type: '' as any, - name: 'User', - description: '', - widget_params: null, - widget_options: null, - }, - { - field_name: 'status', - widget_type: 'Select' as any, - name: '', - description: '', - widget_params: - '// provide array of options to map database value (key \'value\') in human readable value (key \'label\');\n// for example:\n// AK => Alaska,\n// CA => California\n\n{\n "allow_null": true,\n "options": [\n {\n "value": "confirmed",\n "label": "⭐ Confirmed"\n },\n {\n "value": "checked_in",\n "label": "✅ Checked in"\n },\n {\n "value": "cancelled",\n "label": "❌ Cancelled"\n }\n ]\n}', - widget_options: null, - }, - ]; - const newWidgets = createEventAttendeeWidgetsData.map((widget) => { - const newWidget = buildNewTableWidgetEntity(widget); - newWidget.settings = foundEventAttendeeTableSettings; - return newWidget; - }); - await this._dbContext.tableWidgetsRepository.save(newWidgets); - } + private async createDemoMySQLTablesWidgets(tableSettings: Array): Promise { + const foundEventTableSettings = tableSettings.find((settings) => settings.table_name === 'event'); + if (foundEventTableSettings) { + const createEventWidgetsData: Array = [ + { + field_name: 'organizer_id', + widget_type: '' as any, + name: 'Organizer', + description: '', + widget_params: null, + widget_options: null, + }, + { + field_name: 'space_id', + widget_type: '' as any, + name: 'Space', + description: '', + widget_params: null, + widget_options: null, + }, + { + field_name: 'start_time', + widget_type: '' as any, + name: 'Starts at', + description: '', + widget_params: null, + widget_options: null, + }, + { + field_name: 'end_time', + widget_type: '' as any, + name: 'Ends at', + description: '', + widget_params: null, + widget_options: null, + }, + { + field_name: 'title', + widget_type: '' as any, + name: 'Event name', + description: '', + widget_params: null, + widget_options: null, + }, + { + field_name: 'image_url', + widget_type: 'Image' as any, + name: 'Poster', + description: '', + widget_params: + '// provide image height in px to dispaly in table\n// prefix: optional URL prefix to prepend to image source\n// example:\n{\n "height": 100,\n "prefix": "https://demo-data.rocketadmin.com/mysql-demo-images/"\n}\n', + widget_options: null, + }, + ]; + const newWidgets = createEventWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundEventTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } + const foundEventAttendeeTableSettings = tableSettings.find((settings) => settings.table_name === 'event_attendee'); + if (foundEventAttendeeTableSettings) { + const createEventAttendeeWidgetsData: Array = [ + { + field_name: 'event_id', + widget_type: '' as any, + name: 'Event', + description: '', + widget_params: null, + widget_options: null, + }, + { + field_name: 'user_id', + widget_type: '' as any, + name: 'User', + description: '', + widget_params: null, + widget_options: null, + }, + { + field_name: 'status', + widget_type: 'Select' as any, + name: '', + description: '', + widget_params: + '// provide array of options to map database value (key \'value\') in human readable value (key \'label\');\n// for example:\n// AK => Alaska,\n// CA => California\n\n{\n "allow_null": true,\n "options": [\n {\n "value": "confirmed",\n "label": "⭐ Confirmed"\n },\n {\n "value": "checked_in",\n "label": "✅ Checked in"\n },\n {\n "value": "cancelled",\n "label": "❌ Cancelled"\n }\n ]\n}', + widget_options: null, + }, + ]; + const newWidgets = createEventAttendeeWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundEventAttendeeTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } - const foundLocationTableSettings = tableSettings.find((settings) => settings.table_name === 'location'); - if (foundLocationTableSettings) { - const createLocationWidgetsData: Array = [ - { - field_name: 'country', - widget_type: 'Country' as any, - name: '', - description: '', - widget_params: - '// Configure country display options\n// Example:\n{\n "show_flag": true,\n "allow_null": false\n}\n', - widget_options: null, - }, - ]; - const newWidgets = createLocationWidgetsData.map((widget) => { - const newWidget = buildNewTableWidgetEntity(widget); - newWidget.settings = foundLocationTableSettings; - return newWidget; - }); - await this._dbContext.tableWidgetsRepository.save(newWidgets); - } + const foundLocationTableSettings = tableSettings.find((settings) => settings.table_name === 'location'); + if (foundLocationTableSettings) { + const createLocationWidgetsData: Array = [ + { + field_name: 'country', + widget_type: 'Country' as any, + name: '', + description: '', + widget_params: + '// Configure country display options\n// Example:\n{\n "show_flag": true,\n "allow_null": false\n}\n', + widget_options: null, + }, + ]; + const newWidgets = createLocationWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundLocationTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } - const foundMembershipTableSettings = tableSettings.find((settings) => settings.table_name === 'membership'); - if (foundMembershipTableSettings) { - const createMembershipWidgetsData: Array = [ - { - field_name: 'user_id', - widget_type: '' as any, - name: 'User', - description: '', - widget_params: '', - widget_options: null, - }, - { - field_name: 'space_id', - widget_type: '' as any, - name: 'Space', - description: '', - widget_params: '', - widget_options: null, - }, - ]; - const newWidgets = createMembershipWidgetsData.map((widget) => { - const newWidget = buildNewTableWidgetEntity(widget); - newWidget.settings = foundMembershipTableSettings; - return newWidget; - }); - await this._dbContext.tableWidgetsRepository.save(newWidgets); - } + const foundMembershipTableSettings = tableSettings.find((settings) => settings.table_name === 'membership'); + if (foundMembershipTableSettings) { + const createMembershipWidgetsData: Array = [ + { + field_name: 'user_id', + widget_type: '' as any, + name: 'User', + description: '', + widget_params: '', + widget_options: null, + }, + { + field_name: 'space_id', + widget_type: '' as any, + name: 'Space', + description: '', + widget_params: '', + widget_options: null, + }, + ]; + const newWidgets = createMembershipWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundMembershipTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } - const foundSpaceTableSettings = tableSettings.find((settings) => settings.table_name === 'space'); - if (foundSpaceTableSettings) { - const createSpaceWidgetsData: Array = [ - { - field_name: 'type', - widget_type: 'Select' as any, - name: '', - description: '', - widget_params: - '// provide array of options to map database value (key \'value\') in human readable value (key \'label\');\n// for example:\n// AK => Alaska,\n// CA => California\n\n{\n "allow_null": false,\n "options": [\n {\n "value": "private_office",\n "label": "Private office"\n },\n {\n "value": "meeting_room",\n "label": "Meeting room"\n },\n {\n "value": "conference_room",\n "label": "Conference room"\n },\n {\n "value": "event_stage",\n "label": "Event stage"\n },\n {\n "value": "hot_desk",\n "label": "Hot desk"\n }\n ]\n}', - widget_options: null, - }, - { - field_name: 'location_id', - widget_type: '' as any, - name: 'Location', - description: '', - widget_params: null, - widget_options: null, - }, - { - field_name: 'price_per_hour', - widget_type: 'Money' as any, - name: '', - description: '', - widget_params: - '// Configure money widget settings\n// example:\n{\n "default_currency": "USD",\n "decimal_places": 2,\n "allow_negative": true\n}\n', - widget_options: null, - }, - ]; - const newWidgets = createSpaceWidgetsData.map((widget) => { - const newWidget = buildNewTableWidgetEntity(widget); - newWidget.settings = foundSpaceTableSettings; - return newWidget; - }); - await this._dbContext.tableWidgetsRepository.save(newWidgets); - } - const foundUserTableSettings = tableSettings.find((settings) => settings.table_name === 'user'); - if (foundUserTableSettings) { - const createUserWidgetsData: Array = [ - { - field_name: 'role', - widget_type: 'Select' as any, - name: '', - description: '', - widget_params: - '// provide array of options to map database value (key \'value\') in human readable value (key \'label\');\n// for example:\n// AK => Alaska,\n// CA => California\n\n{\n "allow_null": false,\n "options": [\n {\n "value": "admin",\n "label": "👑 Admin"\n },\n {\n "value": "organizer",\n "label": "👩‍💻 Organizer"\n },\n {\n "value": "member",\n "label": "🙍🏻‍♂️ Member"\n }\n ]\n}', - widget_options: null, - }, - { - field_name: 'phone', - widget_type: 'Phone' as any, - name: '', - description: '', - widget_params: - '// Configure international phone number widget\n// example:\n{\n "preferred_countries": ["US", "GB", "CA"],\n "enable_placeholder": true,\n "phone_validation": true\n}\n', - widget_options: null, - }, - ]; - const newWidgets = createUserWidgetsData.map((widget) => { - const newWidget = buildNewTableWidgetEntity(widget); - newWidget.settings = foundUserTableSettings; - return newWidget; - }); - await this._dbContext.tableWidgetsRepository.save(newWidgets); - } - } + const foundSpaceTableSettings = tableSettings.find((settings) => settings.table_name === 'space'); + if (foundSpaceTableSettings) { + const createSpaceWidgetsData: Array = [ + { + field_name: 'type', + widget_type: 'Select' as any, + name: '', + description: '', + widget_params: + '// provide array of options to map database value (key \'value\') in human readable value (key \'label\');\n// for example:\n// AK => Alaska,\n// CA => California\n\n{\n "allow_null": false,\n "options": [\n {\n "value": "private_office",\n "label": "Private office"\n },\n {\n "value": "meeting_room",\n "label": "Meeting room"\n },\n {\n "value": "conference_room",\n "label": "Conference room"\n },\n {\n "value": "event_stage",\n "label": "Event stage"\n },\n {\n "value": "hot_desk",\n "label": "Hot desk"\n }\n ]\n}', + widget_options: null, + }, + { + field_name: 'location_id', + widget_type: '' as any, + name: 'Location', + description: '', + widget_params: null, + widget_options: null, + }, + { + field_name: 'price_per_hour', + widget_type: 'Money' as any, + name: '', + description: '', + widget_params: + '// Configure money widget settings\n// example:\n{\n "default_currency": "USD",\n "decimal_places": 2,\n "allow_negative": true\n}\n', + widget_options: null, + }, + ]; + const newWidgets = createSpaceWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundSpaceTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } + const foundUserTableSettings = tableSettings.find((settings) => settings.table_name === 'user'); + if (foundUserTableSettings) { + const createUserWidgetsData: Array = [ + { + field_name: 'role', + widget_type: 'Select' as any, + name: '', + description: '', + widget_params: + '// provide array of options to map database value (key \'value\') in human readable value (key \'label\');\n// for example:\n// AK => Alaska,\n// CA => California\n\n{\n "allow_null": false,\n "options": [\n {\n "value": "admin",\n "label": "👑 Admin"\n },\n {\n "value": "organizer",\n "label": "👩‍💻 Organizer"\n },\n {\n "value": "member",\n "label": "🙍🏻‍♂️ Member"\n }\n ]\n}', + widget_options: null, + }, + { + field_name: 'phone', + widget_type: 'Phone' as any, + name: '', + description: '', + widget_params: + '// Configure international phone number widget\n// example:\n{\n "preferred_countries": ["US", "GB", "CA"],\n "enable_placeholder": true,\n "phone_validation": true\n}\n', + widget_options: null, + }, + ]; + const newWidgets = createUserWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundUserTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } + } - private async createMySQLDemoTableActions(connection: ConnectionEntity): Promise { - const actionRulesData: Array = [ - { - table_name: 'user', - rule_title: 'Blacklist', - }, - { - table_name: 'user', - rule_title: 'Notification on new user', - }, - ]; - const savedEmptyActionRules = []; - for (const rule_data of actionRulesData) { - const newActionRule = buildEmptyActionRule(rule_data, connection); - const savedActionRule = await this._dbContext.actionRulesRepository.saveNewOrUpdatedActionRule(newActionRule); - savedEmptyActionRules.push(savedActionRule); - } - const foundSavedUserBlacklistActionRule = savedEmptyActionRules.find( - (rule) => rule.table_name === 'user' && rule.rule_title === 'Blacklist', - ); - if (foundSavedUserBlacklistActionRule) { - const createActionEventData: CreateTableActionEventDS = { - event: TableActionEventEnum.CUSTOM, - event_title: 'Blacklist', - icon: 'do_not_disturb_on_total_silence', - require_confirmation: true, - type: TableActionTypeEnum.single, - }; - const newActionEvent = buildActionEventWithRule(createActionEventData, foundSavedUserBlacklistActionRule); - await this._dbContext.actionEventsRepository.saveNewOrUpdatedActionEvent(newActionEvent); - } - const foundSavedUserNotificationActionRule = savedEmptyActionRules.find( - (rule) => rule.table_name === 'user' && rule.rule_title === 'Notification on new user', - ); - if (foundSavedUserNotificationActionRule) { - const createActionEventData: Array = [ - { - event: TableActionEventEnum.ADD_ROW, - event_title: null, - icon: null, - require_confirmation: false, - type: TableActionTypeEnum.single, - }, - { - event: TableActionEventEnum.UPDATE_ROW, - event_title: null, - icon: null, - require_confirmation: false, - type: TableActionTypeEnum.single, - }, - { - event: TableActionEventEnum.DELETE_ROW, - event_title: null, - icon: null, - require_confirmation: false, - type: TableActionTypeEnum.single, - }, - ]; - for (const actionEventData of createActionEventData) { - const newActionEvent = buildActionEventWithRule(actionEventData, foundSavedUserNotificationActionRule); - await this._dbContext.actionEventsRepository.saveNewOrUpdatedActionEvent(newActionEvent); - } - } - } + private async createMySQLDemoTableActions(connection: ConnectionEntity): Promise { + const actionRulesData: Array = [ + { + table_name: 'user', + rule_title: 'Blacklist', + }, + { + table_name: 'user', + rule_title: 'Notification on new user', + }, + ]; + const savedEmptyActionRules = []; + for (const rule_data of actionRulesData) { + const newActionRule = buildEmptyActionRule(rule_data, connection); + const savedActionRule = await this._dbContext.actionRulesRepository.saveNewOrUpdatedActionRule(newActionRule); + savedEmptyActionRules.push(savedActionRule); + } + const foundSavedUserBlacklistActionRule = savedEmptyActionRules.find( + (rule) => rule.table_name === 'user' && rule.rule_title === 'Blacklist', + ); + if (foundSavedUserBlacklistActionRule) { + const createActionEventData: CreateTableActionEventDS = { + event: TableActionEventEnum.CUSTOM, + event_title: 'Blacklist', + icon: 'do_not_disturb_on_total_silence', + require_confirmation: true, + type: TableActionTypeEnum.single, + }; + const newActionEvent = buildActionEventWithRule(createActionEventData, foundSavedUserBlacklistActionRule); + await this._dbContext.actionEventsRepository.saveNewOrUpdatedActionEvent(newActionEvent); + } + const foundSavedUserNotificationActionRule = savedEmptyActionRules.find( + (rule) => rule.table_name === 'user' && rule.rule_title === 'Notification on new user', + ); + if (foundSavedUserNotificationActionRule) { + const createActionEventData: Array = [ + { + event: TableActionEventEnum.ADD_ROW, + event_title: null, + icon: null, + require_confirmation: false, + type: TableActionTypeEnum.single, + }, + { + event: TableActionEventEnum.UPDATE_ROW, + event_title: null, + icon: null, + require_confirmation: false, + type: TableActionTypeEnum.single, + }, + { + event: TableActionEventEnum.DELETE_ROW, + event_title: null, + icon: null, + require_confirmation: false, + type: TableActionTypeEnum.single, + }, + ]; + for (const actionEventData of createActionEventData) { + const newActionEvent = buildActionEventWithRule(actionEventData, foundSavedUserNotificationActionRule); + await this._dbContext.actionEventsRepository.saveNewOrUpdatedActionEvent(newActionEvent); + } + } + } - private async createConnectionPropertiesForMySQLDemoData(connection: ConnectionEntity): Promise { - const createPropertiesData: CreateConnectionPropertiesDs = { - hidden_tables: [], - logo_url: - 'https://demo-data.rocketadmin.com/postgres-demo-images/assets_task_01k04f14nee91t3zf3kfdfhphg_1752496717_img_1-1.webp', - primary_color: '#4CA1F7', - secondary_color: '#E94A74', - hostname: null, - company_name: 'CoworkingHub', - tables_audit: true, - connectionId: '2e42cbbb-794c-4b9f-83b2-0951bdb0a891', - human_readable_table_names: true, - allow_ai_requests: true, - default_showing_table: 'event', - userId: connection?.author?.id || null, - master_password: null, - table_categories: null, - }; - const connectionProperties = buildConnectionPropertiesEntity(createPropertiesData, connection); - await this._dbContext.connectionPropertiesRepository.saveNewConnectionProperties(connectionProperties); - } + private async createConnectionPropertiesForMySQLDemoData(connection: ConnectionEntity): Promise { + const createPropertiesData: CreateConnectionPropertiesDs = { + hidden_tables: [], + logo_url: + 'https://demo-data.rocketadmin.com/postgres-demo-images/assets_task_01k04f14nee91t3zf3kfdfhphg_1752496717_img_1-1.webp', + primary_color: '#4CA1F7', + secondary_color: '#E94A74', + hostname: null, + company_name: 'CoworkingHub', + tables_audit: true, + connectionId: '2e42cbbb-794c-4b9f-83b2-0951bdb0a891', + human_readable_table_names: true, + allow_ai_requests: true, + default_showing_table: 'event', + userId: connection?.author?.id || null, + master_password: null, + table_categories: null, + }; + const connectionProperties = buildConnectionPropertiesEntity(createPropertiesData, connection); + await this._dbContext.connectionPropertiesRepository.saveNewConnectionProperties(connectionProperties); + } - private async createPostgresDemoTableActions(connection: ConnectionEntity): Promise { - const actionRulesData: Array = [ - { - table_name: 'certificates', - rule_title: 'download ', - }, - { - table_name: 'courses', - rule_title: 'Publish', - }, - ]; + private async createPostgresDemoTableActions(connection: ConnectionEntity): Promise { + const actionRulesData: Array = [ + { + table_name: 'certificates', + rule_title: 'download ', + }, + { + table_name: 'courses', + rule_title: 'Publish', + }, + ]; - const savedEmptyActionRules = []; - for (const rule_data of actionRulesData) { - const newActionRule = buildEmptyActionRule(rule_data, connection); - const savedActionRule = await this._dbContext.actionRulesRepository.saveNewOrUpdatedActionRule(newActionRule); - savedEmptyActionRules.push(savedActionRule); - } + const savedEmptyActionRules = []; + for (const rule_data of actionRulesData) { + const newActionRule = buildEmptyActionRule(rule_data, connection); + const savedActionRule = await this._dbContext.actionRulesRepository.saveNewOrUpdatedActionRule(newActionRule); + savedEmptyActionRules.push(savedActionRule); + } - const foundSavedCertificatesActionRule = savedEmptyActionRules.find((rule) => rule.table_name === 'certificates'); - if (foundSavedCertificatesActionRule) { - const createActionEventData: CreateTableActionEventDS = { - event: TableActionEventEnum.CUSTOM, - event_title: 'Download PDF', - icon: 'download', - require_confirmation: false, - type: TableActionTypeEnum.single, - }; - const newActionEvent = buildActionEventWithRule(createActionEventData, foundSavedCertificatesActionRule); - await this._dbContext.actionEventsRepository.saveNewOrUpdatedActionEvent(newActionEvent); - } + const foundSavedCertificatesActionRule = savedEmptyActionRules.find((rule) => rule.table_name === 'certificates'); + if (foundSavedCertificatesActionRule) { + const createActionEventData: CreateTableActionEventDS = { + event: TableActionEventEnum.CUSTOM, + event_title: 'Download PDF', + icon: 'download', + require_confirmation: false, + type: TableActionTypeEnum.single, + }; + const newActionEvent = buildActionEventWithRule(createActionEventData, foundSavedCertificatesActionRule); + await this._dbContext.actionEventsRepository.saveNewOrUpdatedActionEvent(newActionEvent); + } - const foundSavedCoursesActionRule = savedEmptyActionRules.find((rule) => rule.table_name === 'courses'); - if (foundSavedCoursesActionRule) { - const createActionEventData: CreateTableActionEventDS = { - event: TableActionEventEnum.CUSTOM, - event_title: 'Update course data', - icon: 'send', - require_confirmation: true, - type: TableActionTypeEnum.single, - }; - const newActionEvent = buildActionEventWithRule(createActionEventData, foundSavedCoursesActionRule); - await this._dbContext.actionEventsRepository.saveNewOrUpdatedActionEvent(newActionEvent); - } - } + const foundSavedCoursesActionRule = savedEmptyActionRules.find((rule) => rule.table_name === 'courses'); + if (foundSavedCoursesActionRule) { + const createActionEventData: CreateTableActionEventDS = { + event: TableActionEventEnum.CUSTOM, + event_title: 'Update course data', + icon: 'send', + require_confirmation: true, + type: TableActionTypeEnum.single, + }; + const newActionEvent = buildActionEventWithRule(createActionEventData, foundSavedCoursesActionRule); + await this._dbContext.actionEventsRepository.saveNewOrUpdatedActionEvent(newActionEvent); + } + } - private async createConnectionPropertiesForPostgresDemoData( - connection: ConnectionEntity, - ): Promise { - const createPropertiesData: CreateConnectionPropertiesDs = { - hidden_tables: [], - logo_url: - 'https://demo-data.rocketadmin.com/postgres-demo-images/assets_task_01k04ftq4ce4dtg0td6g3d8x6f_1752497601_img_1-1.webp', - primary_color: '#8CBF77', - secondary_color: '#FB8837', - hostname: null, - company_name: 'School of Fish', - tables_audit: true, - connectionId: 'JeVyEzZY', - human_readable_table_names: true, - allow_ai_requests: true, - default_showing_table: 'enrollments', - userId: connection?.author?.id || null, - master_password: null, - table_categories: null, - }; - const connectionProperties = buildConnectionPropertiesEntity(createPropertiesData, connection); - return await this._dbContext.connectionPropertiesRepository.saveNewConnectionProperties(connectionProperties); - } + private async createConnectionPropertiesForPostgresDemoData( + connection: ConnectionEntity, + ): Promise { + const createPropertiesData: CreateConnectionPropertiesDs = { + hidden_tables: [], + logo_url: + 'https://demo-data.rocketadmin.com/postgres-demo-images/assets_task_01k04ftq4ce4dtg0td6g3d8x6f_1752497601_img_1-1.webp', + primary_color: '#8CBF77', + secondary_color: '#FB8837', + hostname: null, + company_name: 'School of Fish', + tables_audit: true, + connectionId: 'JeVyEzZY', + human_readable_table_names: true, + allow_ai_requests: true, + default_showing_table: 'enrollments', + userId: connection?.author?.id || null, + master_password: null, + table_categories: null, + }; + const connectionProperties = buildConnectionPropertiesEntity(createPropertiesData, connection); + return await this._dbContext.connectionPropertiesRepository.saveNewConnectionProperties(connectionProperties); + } - private async createMySQLPostgresSavedTableFilters(connection: ConnectionEntity): Promise { - const savedFiltersData: Array = [ - { - filters: { type: { eq: 'event_stage' } }, - table_name: 'space', - connection_id: connection.id, - filter_name: 'Stage capacity', - dynamic_filtered_column: { column_name: 'capacity', comparator: FilterCriteriaEnum.gt }, - masterPwd: null, - }, - { - filters: { type: { eq: 'hot_desk' } }, - table_name: 'space', - connection_id: connection.id, - filter_name: 'Hot desks', - dynamic_filtered_column: { column_name: 'location_id', comparator: FilterCriteriaEnum.eq }, - masterPwd: null, - }, - { - filters: { role: { eq: 'member' } }, - table_name: 'user', - connection_id: connection.id, - filter_name: 'Members', - dynamic_filtered_column: { column_name: 'email', comparator: FilterCriteriaEnum.contains }, - masterPwd: null, - }, - { - filters: { role: { eq: 'admin' } }, - table_name: 'user', - connection_id: connection.id, - filter_name: 'Admins', - dynamic_filtered_column: { column_name: 'name', comparator: FilterCriteriaEnum.contains }, - masterPwd: null, - }, - { - filters: { organizer_id: { eq: 6 } }, - table_name: 'event', - connection_id: connection.id, - filter_name: "Fiona's events", - dynamic_filtered_column: { column_name: 'title', comparator: FilterCriteriaEnum.contains }, - masterPwd: null, - }, - { - filters: { organizer_id: { eq: 3 } }, - table_name: 'event', - connection_id: connection.id, - filter_name: "Charlie's events", - dynamic_filtered_column: { column_name: 'title', comparator: FilterCriteriaEnum.contains }, - masterPwd: null, - }, - ]; - const filterEntities = savedFiltersData.map((dto) => { - return buildNewTableFiltersEntity(dto); - }); - await this._dbContext.tableFiltersRepository.save(filterEntities); - } + private async createMySQLPostgresSavedTableFilters(connection: ConnectionEntity): Promise { + const savedFiltersData: Array = [ + { + filters: { type: { eq: 'event_stage' } }, + table_name: 'space', + connection_id: connection.id, + filter_name: 'Stage capacity', + dynamic_filtered_column: { column_name: 'capacity', comparator: FilterCriteriaEnum.gt }, + masterPwd: null, + }, + { + filters: { type: { eq: 'hot_desk' } }, + table_name: 'space', + connection_id: connection.id, + filter_name: 'Hot desks', + dynamic_filtered_column: { column_name: 'location_id', comparator: FilterCriteriaEnum.eq }, + masterPwd: null, + }, + { + filters: { role: { eq: 'member' } }, + table_name: 'user', + connection_id: connection.id, + filter_name: 'Members', + dynamic_filtered_column: { column_name: 'email', comparator: FilterCriteriaEnum.contains }, + masterPwd: null, + }, + { + filters: { role: { eq: 'admin' } }, + table_name: 'user', + connection_id: connection.id, + filter_name: 'Admins', + dynamic_filtered_column: { column_name: 'name', comparator: FilterCriteriaEnum.contains }, + masterPwd: null, + }, + { + filters: { organizer_id: { eq: 6 } }, + table_name: 'event', + connection_id: connection.id, + filter_name: "Fiona's events", + dynamic_filtered_column: { column_name: 'title', comparator: FilterCriteriaEnum.contains }, + masterPwd: null, + }, + { + filters: { organizer_id: { eq: 3 } }, + table_name: 'event', + connection_id: connection.id, + filter_name: "Charlie's events", + dynamic_filtered_column: { column_name: 'title', comparator: FilterCriteriaEnum.contains }, + masterPwd: null, + }, + ]; + const filterEntities = savedFiltersData.map((dto) => { + return buildNewTableFiltersEntity(dto); + }); + await this._dbContext.tableFiltersRepository.save(filterEntities); + } - private async createTestTableSettingsPostgres(connection: ConnectionEntity): Promise> { - const tableSettingsDtos: Array = [ - { - table_name: 'certificates', - display_name: null, - search_fields: [], - excluded_fields: [], - readonly_fields: [], - sortable_by: [], - autocomplete_columns: [], - identification_fields: [], - identity_column: 'course_id', - can_delete: true, - can_update: true, - can_add: true, - sensitive_fields: [], - icon: 'workspace_premium', - allow_csv_export: true, - allow_csv_import: true, - connection_id: connection.id, - masterPwd: null, - userId: connection?.author?.id || null, - }, - { - table_name: 'course_mentors', - display_name: null, - search_fields: [], - excluded_fields: [], - readonly_fields: [], - sortable_by: [], - autocomplete_columns: [], - identification_fields: [], - identity_column: 'user_id', - can_delete: true, - can_update: true, - can_add: true, - sensitive_fields: null, - icon: 'co_present', - allow_csv_export: true, - allow_csv_import: true, - connection_id: connection.id, - masterPwd: null, - userId: connection?.author?.id || null, - }, - { - table_name: 'course_modules', - display_name: null, - search_fields: [], - excluded_fields: [], - readonly_fields: [], - sortable_by: [], - autocomplete_columns: [], - identification_fields: [], - identity_column: 'title', - can_delete: true, - can_update: true, - can_add: true, - sensitive_fields: [], - icon: 'dashboard_2', - allow_csv_export: true, - allow_csv_import: true, - connection_id: connection.id, - masterPwd: null, - userId: connection?.author?.id || null, - }, - { - table_name: 'courses', - display_name: null, - search_fields: [], - excluded_fields: [], - readonly_fields: [], - sortable_by: [], - autocomplete_columns: [], - identification_fields: [], - identity_column: 'title', - can_delete: true, - can_update: true, - can_add: true, - sensitive_fields: [], - icon: 'book_ribbon', - allow_csv_export: true, - allow_csv_import: true, - connection_id: connection.id, - masterPwd: null, - userId: connection?.author?.id || null, - }, - { - table_name: 'enrollments', - display_name: '', - search_fields: [], - excluded_fields: [], - readonly_fields: [], - sortable_by: [], - autocomplete_columns: [], - identification_fields: [], - identity_column: 'user_id', - can_delete: true, - can_update: true, - can_add: true, - sensitive_fields: [], - icon: 'how_to_reg', - allow_csv_export: true, - allow_csv_import: true, - connection_id: connection.id, - masterPwd: null, - userId: connection?.author?.id || null, - }, - { - table_name: 'lessons', - display_name: null, - search_fields: [], - excluded_fields: [], - readonly_fields: [], - sortable_by: [], - autocomplete_columns: [], - identification_fields: [], - identity_column: 'title', - can_delete: true, - can_update: true, - can_add: true, - sensitive_fields: null, - icon: 'local_library', - allow_csv_export: true, - allow_csv_import: true, - connection_id: connection.id, - masterPwd: null, - userId: connection?.author?.id || null, - }, - { - table_name: 'quiz_attempts', - display_name: null, - search_fields: [], - excluded_fields: [], - readonly_fields: ['completed_at'], - sortable_by: [], - autocomplete_columns: [], - identification_fields: [], - identity_column: 'user_id', - can_delete: true, - can_update: true, - can_add: true, - sensitive_fields: null, - icon: 'add_task', - allow_csv_export: true, - allow_csv_import: true, - connection_id: connection.id, - masterPwd: null, - userId: connection?.author?.id || null, - }, - { - table_name: 'quizzes', - display_name: null, - search_fields: ['lesson_id', 'title'], - excluded_fields: [], - readonly_fields: [], - sortable_by: [], - autocomplete_columns: ['title'], - identification_fields: [], - identity_column: 'title', - can_delete: true, - can_update: true, - can_add: true, - sensitive_fields: null, - icon: 'edit_document', - allow_csv_export: false, - allow_csv_import: true, - connection_id: connection.id, - masterPwd: null, - userId: connection?.author?.id || null, - }, - { - table_name: 'users', - display_name: '', - search_fields: ['role', 'full_name', 'email', 'bio'], - excluded_fields: [], - readonly_fields: [], - sortable_by: [], - autocomplete_columns: ['role', 'full_name', 'email', 'bio'], - identification_fields: [], - identity_column: 'full_name', - can_delete: true, - can_update: true, - can_add: true, - sensitive_fields: ['email', 'date_of_birth'], - icon: 'groups_3', - allow_csv_export: true, - allow_csv_import: true, - connection_id: connection.id, - masterPwd: null, - userId: connection?.author?.id || null, - }, - ]; + private async createTestTableSettingsPostgres(connection: ConnectionEntity): Promise> { + const tableSettingsDtos: Array = [ + { + table_name: 'certificates', + display_name: null, + search_fields: [], + excluded_fields: [], + readonly_fields: [], + sortable_by: [], + autocomplete_columns: [], + identification_fields: [], + identity_column: 'course_id', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: 'workspace_premium', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'course_mentors', + display_name: null, + search_fields: [], + excluded_fields: [], + readonly_fields: [], + sortable_by: [], + autocomplete_columns: [], + identification_fields: [], + identity_column: 'user_id', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: null, + icon: 'co_present', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'course_modules', + display_name: null, + search_fields: [], + excluded_fields: [], + readonly_fields: [], + sortable_by: [], + autocomplete_columns: [], + identification_fields: [], + identity_column: 'title', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: 'dashboard_2', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'courses', + display_name: null, + search_fields: [], + excluded_fields: [], + readonly_fields: [], + sortable_by: [], + autocomplete_columns: [], + identification_fields: [], + identity_column: 'title', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: 'book_ribbon', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'enrollments', + display_name: '', + search_fields: [], + excluded_fields: [], + readonly_fields: [], + sortable_by: [], + autocomplete_columns: [], + identification_fields: [], + identity_column: 'user_id', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: [], + icon: 'how_to_reg', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'lessons', + display_name: null, + search_fields: [], + excluded_fields: [], + readonly_fields: [], + sortable_by: [], + autocomplete_columns: [], + identification_fields: [], + identity_column: 'title', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: null, + icon: 'local_library', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'quiz_attempts', + display_name: null, + search_fields: [], + excluded_fields: [], + readonly_fields: ['completed_at'], + sortable_by: [], + autocomplete_columns: [], + identification_fields: [], + identity_column: 'user_id', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: null, + icon: 'add_task', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'quizzes', + display_name: null, + search_fields: ['lesson_id', 'title'], + excluded_fields: [], + readonly_fields: [], + sortable_by: [], + autocomplete_columns: ['title'], + identification_fields: [], + identity_column: 'title', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: null, + icon: 'edit_document', + allow_csv_export: false, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + { + table_name: 'users', + display_name: '', + search_fields: ['role', 'full_name', 'email', 'bio'], + excluded_fields: [], + readonly_fields: [], + sortable_by: [], + autocomplete_columns: ['role', 'full_name', 'email', 'bio'], + identification_fields: [], + identity_column: 'full_name', + can_delete: true, + can_update: true, + can_add: true, + sensitive_fields: ['email', 'date_of_birth'], + icon: 'groups_3', + allow_csv_export: true, + allow_csv_import: true, + connection_id: connection.id, + masterPwd: null, + userId: connection?.author?.id || null, + }, + ]; - const tableSettingEntities = tableSettingsDtos.map((dto) => { - return buildNewTableSettingsEntity(dto, connection); - }); - const savedTableSettings = await this._dbContext.tableSettingsRepository.save(tableSettingEntities); - await this.createDemoPostgresTablesWidgets(savedTableSettings); - return savedTableSettings; - } + const tableSettingEntities = tableSettingsDtos.map((dto) => { + return buildNewTableSettingsEntity(dto, connection); + }); + const savedTableSettings = await this._dbContext.tableSettingsRepository.save(tableSettingEntities); + await this.createDemoPostgresTablesWidgets(savedTableSettings); + return savedTableSettings; + } - private async createDemoPostgresTablesWidgets(tableSettings: Array): Promise { - const foundCertificatesTableSettings = tableSettings.find((settings) => settings.table_name === 'certificates'); - if (foundCertificatesTableSettings) { - const createCertificatesWidgetsData: Array = [ - { - field_name: 'user_id', - widget_type: '' as any, - name: 'User', - description: '', - widget_params: null, - widget_options: null, - }, - { - field_name: 'certificate_url', - widget_type: 'URL' as any, - name: '', - description: '', - widget_params: - '// prefix: optional URL prefix to prepend to the href\n// example:\n{\n "prefix": "https://certificates.example.com/"\n}\n', - widget_options: null, - }, - { - field_name: 'course_id', - widget_type: '' as any, - name: 'Course', - description: "hi i'm a description", - widget_params: null, - widget_options: null, - }, - ]; - const newWidgets = createCertificatesWidgetsData.map((widget) => { - const newWidget = buildNewTableWidgetEntity(widget); - newWidget.settings = foundCertificatesTableSettings; - return newWidget; - }); - await this._dbContext.tableWidgetsRepository.save(newWidgets); - } - const foundCourseMentorsTableSettings = tableSettings.find((settings) => settings.table_name === 'course_mentors'); - if (foundCourseMentorsTableSettings) { - const createCourseMentorsWidgetsData: Array = [ - { - field_name: 'course_id', - widget_type: '' as any, - name: 'Course', - description: '', - widget_params: '', - widget_options: null, - }, - { - field_name: 'user_id', - widget_type: '' as any, - name: 'User', - description: '', - widget_params: null, - widget_options: null, - }, - ]; - const newWidgets = createCourseMentorsWidgetsData.map((widget) => { - const newWidget = buildNewTableWidgetEntity(widget); - newWidget.settings = foundCourseMentorsTableSettings; - return newWidget; - }); - await this._dbContext.tableWidgetsRepository.save(newWidgets); - } + private async createDemoPostgresTablesWidgets(tableSettings: Array): Promise { + const foundCertificatesTableSettings = tableSettings.find((settings) => settings.table_name === 'certificates'); + if (foundCertificatesTableSettings) { + const createCertificatesWidgetsData: Array = [ + { + field_name: 'user_id', + widget_type: '' as any, + name: 'User', + description: '', + widget_params: null, + widget_options: null, + }, + { + field_name: 'certificate_url', + widget_type: 'URL' as any, + name: '', + description: '', + widget_params: + '// prefix: optional URL prefix to prepend to the href\n// example:\n{\n "prefix": "https://certificates.example.com/"\n}\n', + widget_options: null, + }, + { + field_name: 'course_id', + widget_type: '' as any, + name: 'Course', + description: "hi i'm a description", + widget_params: null, + widget_options: null, + }, + ]; + const newWidgets = createCertificatesWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundCertificatesTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } + const foundCourseMentorsTableSettings = tableSettings.find((settings) => settings.table_name === 'course_mentors'); + if (foundCourseMentorsTableSettings) { + const createCourseMentorsWidgetsData: Array = [ + { + field_name: 'course_id', + widget_type: '' as any, + name: 'Course', + description: '', + widget_params: '', + widget_options: null, + }, + { + field_name: 'user_id', + widget_type: '' as any, + name: 'User', + description: '', + widget_params: null, + widget_options: null, + }, + ]; + const newWidgets = createCourseMentorsWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundCourseMentorsTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } - const foundCourseModulesTableSettings = tableSettings.find((settings) => settings.table_name === 'course_modules'); - if (foundCourseModulesTableSettings) { - const createCourseModulesWidgetsData: Array = [ - { - field_name: 'course_id', - widget_type: '' as any, - name: 'Course', - description: '', - widget_params: '', - widget_options: null, - }, - ]; - const newWidgets = createCourseModulesWidgetsData.map((widget) => { - const newWidget = buildNewTableWidgetEntity(widget); - newWidget.settings = foundCourseModulesTableSettings; - return newWidget; - }); - await this._dbContext.tableWidgetsRepository.save(newWidgets); - } + const foundCourseModulesTableSettings = tableSettings.find((settings) => settings.table_name === 'course_modules'); + if (foundCourseModulesTableSettings) { + const createCourseModulesWidgetsData: Array = [ + { + field_name: 'course_id', + widget_type: '' as any, + name: 'Course', + description: '', + widget_params: '', + widget_options: null, + }, + ]; + const newWidgets = createCourseModulesWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundCourseModulesTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } - const foundCoursesTableSettings = tableSettings.find((settings) => settings.table_name === 'courses'); - if (foundCoursesTableSettings) { - const createCoursesWidgetsData: Array = [ - { - field_name: 'price', - widget_type: 'Money' as any, - name: '', - description: '', - widget_params: - '// Configure money widget settings\n// example:\n{\n "default_currency": "USD",\n "show_currency_selector": false,\n "decimal_places": 2,\n "allow_negative": false\n}\n', - widget_options: null, - }, - ]; - const newWidgets = createCoursesWidgetsData.map((widget) => { - const newWidget = buildNewTableWidgetEntity(widget); - newWidget.settings = foundCoursesTableSettings; - return newWidget; - }); - await this._dbContext.tableWidgetsRepository.save(newWidgets); - } + const foundCoursesTableSettings = tableSettings.find((settings) => settings.table_name === 'courses'); + if (foundCoursesTableSettings) { + const createCoursesWidgetsData: Array = [ + { + field_name: 'price', + widget_type: 'Money' as any, + name: '', + description: '', + widget_params: + '// Configure money widget settings\n// example:\n{\n "default_currency": "USD",\n "show_currency_selector": false,\n "decimal_places": 2,\n "allow_negative": false\n}\n', + widget_options: null, + }, + ]; + const newWidgets = createCoursesWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundCoursesTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } - const foundEnrollmentsTableSettings = tableSettings.find((settings) => settings.table_name === 'enrollments'); - if (foundEnrollmentsTableSettings) { - const createEnrollmentsWidgetsData: Array = [ - { - field_name: 'user_id', - widget_type: '' as any, - name: 'User', - description: '', - widget_params: null, - widget_options: null, - }, - { - field_name: 'course_id', - widget_type: '' as any, - name: 'Course', - description: '', - widget_params: null, - widget_options: null, - }, - { - field_name: 'progress', - widget_type: 'Range' as any, - name: '', - description: '', - widget_params: - '// Configure the minimum, maximum and step values for the range\n// Default: min = 0, max = 100, step = 1\n{\n "min": 0,\n "max": 100,\n "step": 0.01\n}\n', - widget_options: null, - }, - ]; - const newWidgets = createEnrollmentsWidgetsData.map((widget) => { - const newWidget = buildNewTableWidgetEntity(widget); - newWidget.settings = foundEnrollmentsTableSettings; - return newWidget; - }); - await this._dbContext.tableWidgetsRepository.save(newWidgets); - } + const foundEnrollmentsTableSettings = tableSettings.find((settings) => settings.table_name === 'enrollments'); + if (foundEnrollmentsTableSettings) { + const createEnrollmentsWidgetsData: Array = [ + { + field_name: 'user_id', + widget_type: '' as any, + name: 'User', + description: '', + widget_params: null, + widget_options: null, + }, + { + field_name: 'course_id', + widget_type: '' as any, + name: 'Course', + description: '', + widget_params: null, + widget_options: null, + }, + { + field_name: 'progress', + widget_type: 'Range' as any, + name: '', + description: '', + widget_params: + '// Configure the minimum, maximum and step values for the range\n// Default: min = 0, max = 100, step = 1\n{\n "min": 0,\n "max": 100,\n "step": 0.01\n}\n', + widget_options: null, + }, + ]; + const newWidgets = createEnrollmentsWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundEnrollmentsTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } - const foundLessonsTableSettings = tableSettings.find((settings) => settings.table_name === 'lessons'); - if (foundLessonsTableSettings) { - const createLessonsWidgetsData: Array = [ - { - field_name: 'video_url', - widget_type: 'URL' as any, - name: '', - description: '', - widget_params: - '// prefix: optional URL prefix to prepend to the href\n// example:\n{\n "prefix": "https://videos.example.com/"\n}\n', - widget_options: null, - }, - { - field_name: 'module_id', - widget_type: '' as any, - name: 'Module', - description: '', - widget_params: null, - widget_options: null, - }, - { - field_name: 'content_url', - widget_type: 'URL' as any, - name: '', - description: '', - widget_params: - '// prefix: optional URL prefix to prepend to the href\n// example:\n{\n "prefix": "https://content.example.com/"\n}\n', - widget_options: null, - }, - ]; - const newWidgets = createLessonsWidgetsData.map((widget) => { - const newWidget = buildNewTableWidgetEntity(widget); - newWidget.settings = foundLessonsTableSettings; - return newWidget; - }); - await this._dbContext.tableWidgetsRepository.save(newWidgets); - } + const foundLessonsTableSettings = tableSettings.find((settings) => settings.table_name === 'lessons'); + if (foundLessonsTableSettings) { + const createLessonsWidgetsData: Array = [ + { + field_name: 'video_url', + widget_type: 'URL' as any, + name: '', + description: '', + widget_params: + '// prefix: optional URL prefix to prepend to the href\n// example:\n{\n "prefix": "https://videos.example.com/"\n}\n', + widget_options: null, + }, + { + field_name: 'module_id', + widget_type: '' as any, + name: 'Module', + description: '', + widget_params: null, + widget_options: null, + }, + { + field_name: 'content_url', + widget_type: 'URL' as any, + name: '', + description: '', + widget_params: + '// prefix: optional URL prefix to prepend to the href\n// example:\n{\n "prefix": "https://content.example.com/"\n}\n', + widget_options: null, + }, + ]; + const newWidgets = createLessonsWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundLessonsTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } - const foundQuizAttemptsTableSettings = tableSettings.find((settings) => settings.table_name === 'quiz_attempts'); - if (foundQuizAttemptsTableSettings) { - const createQuizAttemptsWidgetsData: Array = [ - { - field_name: 'quiz_id', - widget_type: '' as any, - name: 'Quiz', - description: '', - widget_params: '', - widget_options: null, - }, - { - field_name: 'user_id', - widget_type: '' as any, - name: 'User', - description: '', - widget_params: null, - widget_options: null, - }, - ]; - const newWidgets = createQuizAttemptsWidgetsData.map((widget) => { - const newWidget = buildNewTableWidgetEntity(widget); - newWidget.settings = foundQuizAttemptsTableSettings; - return newWidget; - }); - await this._dbContext.tableWidgetsRepository.save(newWidgets); - } + const foundQuizAttemptsTableSettings = tableSettings.find((settings) => settings.table_name === 'quiz_attempts'); + if (foundQuizAttemptsTableSettings) { + const createQuizAttemptsWidgetsData: Array = [ + { + field_name: 'quiz_id', + widget_type: '' as any, + name: 'Quiz', + description: '', + widget_params: '', + widget_options: null, + }, + { + field_name: 'user_id', + widget_type: '' as any, + name: 'User', + description: '', + widget_params: null, + widget_options: null, + }, + ]; + const newWidgets = createQuizAttemptsWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundQuizAttemptsTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } - const foundQuizzesTableSettings = tableSettings.find((settings) => settings.table_name === 'quizzes'); - if (foundQuizzesTableSettings) { - const createQuizzesWidgetsData: Array = [ - { - field_name: 'lesson_id', - widget_type: '' as any, - name: 'Lesson', - description: '', - widget_params: '', - widget_options: null, - }, - ]; - const newWidgets = createQuizzesWidgetsData.map((widget) => { - const newWidget = buildNewTableWidgetEntity(widget); - newWidget.settings = foundQuizzesTableSettings; - return newWidget; - }); - await this._dbContext.tableWidgetsRepository.save(newWidgets); - } + const foundQuizzesTableSettings = tableSettings.find((settings) => settings.table_name === 'quizzes'); + if (foundQuizzesTableSettings) { + const createQuizzesWidgetsData: Array = [ + { + field_name: 'lesson_id', + widget_type: '' as any, + name: 'Lesson', + description: '', + widget_params: '', + widget_options: null, + }, + ]; + const newWidgets = createQuizzesWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundQuizzesTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } - const foundUsersTableSettings = tableSettings.find((settings) => settings.table_name === 'users'); - if (foundUsersTableSettings) { - const createUsersWidgetsData: Array = [ - { - field_name: 'role', - widget_type: 'Select' as any, - name: '', - description: '', - widget_params: - '{\n "allow_null": false,\n "options": [\n {\n "value": "admin",\n "label": "🥷 Admin"\n },\n {\n "value": "mentor",\n "label": "🧑‍🏫 Mentor"\n },\n {\n "value": "student",\n "label": "🧑‍🎓 Student"\n }\n ]\n}', - widget_options: null, - }, - { - field_name: 'password_hash', - widget_type: 'Password' as any, - name: 'Password', - description: '', - widget_params: - '// provide algorithm to encrypt your password, one of:\n//sha1, sha3, sha224, sha256, sha512, sha384, bcrypt, scrypt, argon2, pbkdf2.\n// example:\n\n{\n "algorithm": "sha224"\n}\n\n', - widget_options: null, - }, - ]; - const newWidgets = createUsersWidgetsData.map((widget) => { - const newWidget = buildNewTableWidgetEntity(widget); - newWidget.settings = foundUsersTableSettings; - return newWidget; - }); - await this._dbContext.tableWidgetsRepository.save(newWidgets); - } - } + const foundUsersTableSettings = tableSettings.find((settings) => settings.table_name === 'users'); + if (foundUsersTableSettings) { + const createUsersWidgetsData: Array = [ + { + field_name: 'role', + widget_type: 'Select' as any, + name: '', + description: '', + widget_params: + '{\n "allow_null": false,\n "options": [\n {\n "value": "admin",\n "label": "🥷 Admin"\n },\n {\n "value": "mentor",\n "label": "🧑‍🏫 Mentor"\n },\n {\n "value": "student",\n "label": "🧑‍🎓 Student"\n }\n ]\n}', + widget_options: null, + }, + { + field_name: 'password_hash', + widget_type: 'Password' as any, + name: 'Password', + description: '', + widget_params: + '// provide algorithm to encrypt your password, one of:\n//sha1, sha3, sha224, sha256, sha512, sha384, bcrypt, scrypt, argon2, pbkdf2.\n// example:\n\n{\n "algorithm": "sha224"\n}\n\n', + widget_options: null, + }, + ]; + const newWidgets = createUsersWidgetsData.map((widget) => { + const newWidget = buildNewTableWidgetEntity(widget); + newWidget.settings = foundUsersTableSettings; + return newWidget; + }); + await this._dbContext.tableWidgetsRepository.save(newWidgets); + } + } - private async createDemoPostgresSavedTableFilters(connection: ConnectionEntity): Promise { - const savedFiltersData: Array = [ - { - filters: { completed: { eq: true } }, - table_name: 'enrollments', - connection_id: connection.id, - filter_name: 'Completed courses', - dynamic_filtered_column: { column_name: 'course_id', comparator: FilterCriteriaEnum.eq }, - masterPwd: null, - }, - { - filters: { price: { gt: 100 }, is_published: { eq: true } }, - table_name: 'courses', - connection_id: connection.id, - filter_name: 'Expensive published', - dynamic_filtered_column: { column_name: 'title', comparator: FilterCriteriaEnum.contains }, - masterPwd: null, - }, - { - filters: { language: { eq: 'en' }, is_published: { eq: true } }, - table_name: 'courses', - connection_id: connection.id, - filter_name: 'Published in English', - dynamic_filtered_column: { column_name: 'title', comparator: FilterCriteriaEnum.contains }, - masterPwd: null, - }, - { - filters: { role: { eq: 'student' } }, - table_name: 'users', - connection_id: connection.id, - filter_name: 'Students', - dynamic_filtered_column: { column_name: 'full_name', comparator: FilterCriteriaEnum.contains }, - masterPwd: null, - }, - { - filters: { role: { eq: 'mentor' } }, - table_name: 'users', - connection_id: connection.id, - filter_name: 'Mentors', - dynamic_filtered_column: { column_name: 'email', comparator: FilterCriteriaEnum.contains }, - masterPwd: null, - }, - ]; - const tableFilterEntities = savedFiltersData.map((dto) => { - return buildNewTableFiltersEntity(dto); - }); - await this._dbContext.tableFiltersRepository.save(tableFilterEntities); - } + private async createDemoPostgresSavedTableFilters(connection: ConnectionEntity): Promise { + const savedFiltersData: Array = [ + { + filters: { completed: { eq: true } }, + table_name: 'enrollments', + connection_id: connection.id, + filter_name: 'Completed courses', + dynamic_filtered_column: { column_name: 'course_id', comparator: FilterCriteriaEnum.eq }, + masterPwd: null, + }, + { + filters: { price: { gt: 100 }, is_published: { eq: true } }, + table_name: 'courses', + connection_id: connection.id, + filter_name: 'Expensive published', + dynamic_filtered_column: { column_name: 'title', comparator: FilterCriteriaEnum.contains }, + masterPwd: null, + }, + { + filters: { language: { eq: 'en' }, is_published: { eq: true } }, + table_name: 'courses', + connection_id: connection.id, + filter_name: 'Published in English', + dynamic_filtered_column: { column_name: 'title', comparator: FilterCriteriaEnum.contains }, + masterPwd: null, + }, + { + filters: { role: { eq: 'student' } }, + table_name: 'users', + connection_id: connection.id, + filter_name: 'Students', + dynamic_filtered_column: { column_name: 'full_name', comparator: FilterCriteriaEnum.contains }, + masterPwd: null, + }, + { + filters: { role: { eq: 'mentor' } }, + table_name: 'users', + connection_id: connection.id, + filter_name: 'Mentors', + dynamic_filtered_column: { column_name: 'email', comparator: FilterCriteriaEnum.contains }, + masterPwd: null, + }, + ]; + const tableFilterEntities = savedFiltersData.map((dto) => { + return buildNewTableFiltersEntity(dto); + }); + await this._dbContext.tableFiltersRepository.save(tableFilterEntities); + } } diff --git a/backend/src/entities/demo-data/demo-deta.module.ts b/backend/src/entities/demo-data/demo-deta.module.ts index b3d0e63b9..36b834594 100644 --- a/backend/src/entities/demo-data/demo-deta.module.ts +++ b/backend/src/entities/demo-data/demo-deta.module.ts @@ -1,23 +1,23 @@ import { Global, MiddlewareConsumer, Module } from '@nestjs/common'; -import { DemoDataService } from './demo-data.service.js'; -import { BaseType } from '../../common/data-injection.tokens.js'; -import { GlobalDatabaseContext } from '../../common/application/global-database-context.js'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { GlobalDatabaseContext } from '../../common/application/global-database-context.js'; +import { BaseType } from '../../common/data-injection.tokens.js'; +import { DemoDataService } from './demo-data.service.js'; @Global() @Module({ - imports: [TypeOrmModule.forFeature([])], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, + imports: [TypeOrmModule.forFeature([])], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, - DemoDataService, - ], - controllers: [], - exports: [DemoDataService], + DemoDataService, + ], + controllers: [], + exports: [DemoDataService], }) export class DemoDataModule { - public configure(_consumer: MiddlewareConsumer): any {} + public configure(_consumer: MiddlewareConsumer): any {} } diff --git a/backend/src/entities/email/email-config/email-config.interface.ts b/backend/src/entities/email/email-config/email-config.interface.ts index 03c7f23f8..70df031ef 100644 --- a/backend/src/entities/email/email-config/email-config.interface.ts +++ b/backend/src/entities/email/email-config/email-config.interface.ts @@ -1,18 +1,18 @@ export interface IEmailConfig { - host: string; - port: number; - secure: boolean; - auth: IAuth; - connectionTimeout?: number; - greetingTimeout?: number; - socketTimeout?: number; + host: string; + port: number; + secure: boolean; + auth: IAuth; + connectionTimeout?: number; + greetingTimeout?: number; + socketTimeout?: number; } export interface IEmailConfigService { - getEmailServiceConfig(): IEmailConfig | Promise | string | Promise; + getEmailServiceConfig(): IEmailConfig | Promise | string | Promise; } interface IAuth { - user: string; - pass: string; + user: string; + pass: string; } diff --git a/backend/src/entities/email/email-config/email-config.service.ts b/backend/src/entities/email/email-config/email-config.service.ts index 8b7bc9867..463554f5c 100644 --- a/backend/src/entities/email/email-config/email-config.service.ts +++ b/backend/src/entities/email/email-config/email-config.service.ts @@ -3,27 +3,27 @@ import { IEmailConfig, IEmailConfigService } from './email-config.interface.js'; @Injectable() export class EmailConfigService implements IEmailConfigService { - public getEmailServiceConfig(): IEmailConfig | string { - const pullConfig = process.env.EMAIL_CONFIG_STRING; - if (pullConfig) { - return pullConfig; - } - const emailServiceHost = process.env.EMAIL_SERVICE_HOST; - const emailServicePort = parseInt(process.env.EMAIL_SERVICE_PORT, 10) || 25; - const emailServiceUserName = process.env.EMAIL_SERVICE_USERNAME; - const emailServicePassword = process.env.EMAIL_SERVICE_PASSWORD; - const nonSecure = !process.env.NON_SSL_EMAIL; - return { - host: emailServiceHost, - port: emailServicePort, - secure: nonSecure, - auth: { - user: emailServiceUserName, - pass: emailServicePassword, - }, - socketTimeout: 4 * 1000, - connectionTimeout: 4 * 1000, - greetingTimeout: 4 * 1000, - }; - } + public getEmailServiceConfig(): IEmailConfig | string { + const pullConfig = process.env.EMAIL_CONFIG_STRING; + if (pullConfig) { + return pullConfig; + } + const emailServiceHost = process.env.EMAIL_SERVICE_HOST; + const emailServicePort = parseInt(process.env.EMAIL_SERVICE_PORT, 10) || 25; + const emailServiceUserName = process.env.EMAIL_SERVICE_USERNAME; + const emailServicePassword = process.env.EMAIL_SERVICE_PASSWORD; + const nonSecure = !process.env.NON_SSL_EMAIL; + return { + host: emailServiceHost, + port: emailServicePort, + secure: nonSecure, + auth: { + user: emailServiceUserName, + pass: emailServicePassword, + }, + socketTimeout: 4 * 1000, + connectionTimeout: 4 * 1000, + greetingTimeout: 4 * 1000, + }; + } } diff --git a/backend/src/entities/email/email-messages/email-message.interface.ts b/backend/src/entities/email/email-messages/email-message.interface.ts index 8c382d839..646845f74 100644 --- a/backend/src/entities/email/email-messages/email-message.interface.ts +++ b/backend/src/entities/email/email-messages/email-message.interface.ts @@ -1,7 +1,7 @@ export interface IEmailMessage { - from: string; - to: string; - subject: string; - text: string; - html?: string; + from: string; + to: string; + subject: string; + text: string; + html?: string; } diff --git a/backend/src/entities/email/email-messages/email-message.ts b/backend/src/entities/email/email-messages/email-message.ts index 869964534..7de2b1870 100644 --- a/backend/src/entities/email/email-messages/email-message.ts +++ b/backend/src/entities/email/email-messages/email-message.ts @@ -1,16 +1,15 @@ import { AbstractEmailLetter } from '../email/abstract-email-letter.js'; -import { IEmailMessage } from './email-message.interface.js'; import { IMessage } from '../email/email.interface.js'; +import { IEmailMessage } from './email-message.interface.js'; export class EmailLetter extends AbstractEmailLetter { - - getEmail(): IMessage { - return { - from: this._params.from, - to: this._params.to, - subject: this._params.subject, - text: this._params.text, - html: this._params.html, - }; - } + getEmail(): IMessage { + return { + from: this._params.from, + to: this._params.to, + subject: this._params.subject, + text: this._params.text, + html: this._params.html, + }; + } } diff --git a/backend/src/entities/email/email-text/email-text.ts b/backend/src/entities/email/email-text/email-text.ts index 425a56dcc..2fbef7947 100644 --- a/backend/src/entities/email/email-text/email-text.ts +++ b/backend/src/entities/email/email-text/email-text.ts @@ -2,78 +2,78 @@ import { UserInfoMessageData } from '../../table-actions/table-actions-module/ta import { escapeHtml } from '../utils/escape-html.util.js'; export const EMAIL_TEXT = { - ROCKETADMIN_REMINDER: { - EMAIL_SUBJECT: 'Can we help you with your Rocketadmin database connection?', - EMAIL_TEXT: `Hi there! + ROCKETADMIN_REMINDER: { + EMAIL_SUBJECT: 'Can we help you with your Rocketadmin database connection?', + EMAIL_TEXT: `Hi there! We saw you tried to connect a database to our tool but didn't finish. Need any help? Just reply to this email, and our support team will be happy to assist! Thanks. `, - }, + }, - COMPANY_2FA_ENABLED: { - EMAIL_SUBJECT: '2FA was enabled in your company', - EMAIL_TEXT: (companyName: string): string => { - companyName = escapeHtml(companyName); - return `Administrator enabled two-factor authentication for you company "${companyName}". Please enable 2FA in your account. It will be required for login soon.`; - }, - }, + COMPANY_2FA_ENABLED: { + EMAIL_SUBJECT: '2FA was enabled in your company', + EMAIL_TEXT: (companyName: string): string => { + companyName = escapeHtml(companyName); + return `Administrator enabled two-factor authentication for you company "${companyName}". Please enable 2FA in your account. It will be required for login soon.`; + }, + }, - INVITE_IN_GROUP: { - EMAIL_SUBJECT: 'You were added to a group on Rocketadmin', - EMAIL_TEXT: (groupTitle: string): string => { - groupTitle = escapeHtml(groupTitle); - return `You have been added to the "${groupTitle}" group. Glad to see you there.`; - }, - }, + INVITE_IN_GROUP: { + EMAIL_SUBJECT: 'You were added to a group on Rocketadmin', + EMAIL_TEXT: (groupTitle: string): string => { + groupTitle = escapeHtml(groupTitle); + return `You have been added to the "${groupTitle}" group. Glad to see you there.`; + }, + }, - INVITE_IN_COMPANY: { - EMAIL_SUBJECT: 'You were invited to a company on Rocketadmin', - EMAIL_TEXT: (link: string, companyName: string) => { - return `You have been added to a company${companyName}in the Rocketadmin project. + INVITE_IN_COMPANY: { + EMAIL_SUBJECT: 'You were invited to a company on Rocketadmin', + EMAIL_TEXT: (link: string, companyName: string) => { + return `You have been added to a company${companyName}in the Rocketadmin project. Please follow the link and accept the invitation: ${link}`; - }, - }, + }, + }, - CONFIRM_EMAIL: { - EMAIL_SUBJECT: `Finish your registration in Rocketadmin`, - EMAIL_TEXT: (link: string) => - `To keep your account secure, we need to verify your email address. Please follow the link to complete the verification. + CONFIRM_EMAIL: { + EMAIL_SUBJECT: `Finish your registration in Rocketadmin`, + EMAIL_TEXT: (link: string) => + `To keep your account secure, we need to verify your email address. Please follow the link to complete the verification. ${link}`, - }, + }, - CHANGED_EMAIL: { - EMAIL_SUBJECT: 'Your Rocketadmin email has been successfully changed', - EMAIL_TEXT: 'Hi! Your email address has been successfully updated. Thanks!', - }, + CHANGED_EMAIL: { + EMAIL_SUBJECT: 'Your Rocketadmin email has been successfully changed', + EMAIL_TEXT: 'Hi! Your email address has been successfully updated. Thanks!', + }, - CHANGE_EMAIL_REQUEST: { - EMAIL_SUBJECT: 'Email Change Request', - EMAIL_TEXT: (link: string) => `We received a request to change your email address. + CHANGE_EMAIL_REQUEST: { + EMAIL_SUBJECT: 'Email Change Request', + EMAIL_TEXT: (link: string) => `We received a request to change your email address. Follow the link to confirm - ${link}. If you didn't request an email change, please contact our support team or reply to this email with your questions.`, - }, + }, - RESET_PASSWORD_REQUEST: { - EMAIL_SUBJECT: 'Reset password request', - EMAIL_TEXT: (link: string) => `We've received a request to change your password. + RESET_PASSWORD_REQUEST: { + EMAIL_SUBJECT: 'Reset password request', + EMAIL_TEXT: (link: string) => `We've received a request to change your password. Follow the link to confirm - ${link}. If you don't use this link within 3 hours, it will expire. If you didn't request a password reset, you can ignore this email; your password will not be changed.`, - }, + }, - ACTION_EMAIL: { - EMAIL_SUBJECT: 'Rocketadmin action notification', - EMAIL_TEXT: ( - userInfo: UserInfoMessageData, - action: string, - tableName: string, - primaryKeyValuesArray: Array>, - ): string => { - const { email, userId, userName } = userInfo; - const textContent = `${userName ? escapeHtml(userName) : 'User'} (email: ${email}, user id: ${userId}) has ${action} in the table "${escapeHtml(tableName)}".`; - return `${textContent} Primary Keys: ${JSON.stringify(primaryKeyValuesArray)}`; - }, - }, + ACTION_EMAIL: { + EMAIL_SUBJECT: 'Rocketadmin action notification', + EMAIL_TEXT: ( + userInfo: UserInfoMessageData, + action: string, + tableName: string, + primaryKeyValuesArray: Array>, + ): string => { + const { email, userId, userName } = userInfo; + const textContent = `${userName ? escapeHtml(userName) : 'User'} (email: ${email}, user id: ${userId}) has ${action} in the table "${escapeHtml(tableName)}".`; + return `${textContent} Primary Keys: ${JSON.stringify(primaryKeyValuesArray)}`; + }, + }, }; diff --git a/backend/src/entities/email/email-verification.entity.ts b/backend/src/entities/email/email-verification.entity.ts index f17a3b79a..072506dbb 100644 --- a/backend/src/entities/email/email-verification.entity.ts +++ b/backend/src/entities/email/email-verification.entity.ts @@ -3,13 +3,17 @@ import { UserEntity } from '../user/user.entity.js'; @Entity('email_verification') export class EmailVerificationEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ default: null }) - verification_string: string; + @Column({ default: null }) + verification_string: string; - @OneToOne(() => UserEntity, (user) => user.email_verification, { onDelete: 'CASCADE' }) - @JoinColumn() - user: Relation; + @OneToOne( + () => UserEntity, + (user) => user.email_verification, + { onDelete: 'CASCADE' }, + ) + @JoinColumn() + user: Relation; } diff --git a/backend/src/entities/email/email/abstract-email-letter.ts b/backend/src/entities/email/email/abstract-email-letter.ts index 7d3715cc0..afd76b7ea 100644 --- a/backend/src/entities/email/email/abstract-email-letter.ts +++ b/backend/src/entities/email/email/abstract-email-letter.ts @@ -2,11 +2,11 @@ import { IMessage } from './email.interface.js'; // eslint-disable-next-line @typescript-eslint/no-empty-object-type export abstract class AbstractEmailLetter { - protected readonly _params: TParams; + protected readonly _params: TParams; - constructor(params: TParams) { - this._params = params; - } + constructor(params: TParams) { + this._params = params; + } - public abstract getEmail(): IMessage; + public abstract getEmail(): IMessage; } diff --git a/backend/src/entities/email/email/email.generator.ts b/backend/src/entities/email/email/email.generator.ts index 75f0983d2..a3c96c7eb 100644 --- a/backend/src/entities/email/email/email.generator.ts +++ b/backend/src/entities/email/email/email.generator.ts @@ -1,8 +1,8 @@ -import { IEmailGenerator, IMessage } from './email.interface.js'; import { AbstractEmailLetter } from './abstract-email-letter.js'; +import { IEmailGenerator, IMessage } from './email.interface.js'; export class EmailGenerator implements IEmailGenerator { - generateEmail(email: AbstractEmailLetter): IMessage { - return email.getEmail(); - } + generateEmail(email: AbstractEmailLetter): IMessage { + return email.getEmail(); + } } diff --git a/backend/src/entities/email/email/email.interface.ts b/backend/src/entities/email/email/email.interface.ts index 1fe043839..c2b17adf0 100644 --- a/backend/src/entities/email/email/email.interface.ts +++ b/backend/src/entities/email/email/email.interface.ts @@ -1,14 +1,13 @@ import { AbstractEmailLetter } from './abstract-email-letter.js'; export interface IMessage { - from: string; - to: string; - subject: string; - text: string; - html?: string; + from: string; + to: string; + subject: string; + text: string; + html?: string; } export interface IEmailGenerator { - generateEmail(email: AbstractEmailLetter): IMessage; + generateEmail(email: AbstractEmailLetter): IMessage; } - diff --git a/backend/src/entities/email/email/email.module.ts b/backend/src/entities/email/email/email.module.ts index ec896c071..bf12cfada 100644 --- a/backend/src/entities/email/email/email.module.ts +++ b/backend/src/entities/email/email/email.module.ts @@ -1,14 +1,14 @@ import { Global, Module } from '@nestjs/common'; -import { EmailService } from './email.service.js'; -import { NunjucksModule } from '../template-engine/nunjucks.module.js'; import { EmailConfigService } from '../email-config/email-config.service.js'; +import { NunjucksModule } from '../template-engine/nunjucks.module.js'; import { EmailTransporterService } from '../transporter/email-transporter-service.js'; +import { EmailService } from './email.service.js'; @Global() @Module({ - imports: [NunjucksModule], - controllers: [], - providers: [EmailService, EmailConfigService, EmailTransporterService], - exports: [EmailService], + imports: [NunjucksModule], + controllers: [], + providers: [EmailService, EmailConfigService, EmailTransporterService], + exports: [EmailService], }) export class EmailModule {} diff --git a/backend/src/entities/email/email/email.service.ts b/backend/src/entities/email/email/email.service.ts index a403fe944..c309d819c 100644 --- a/backend/src/entities/email/email/email.service.ts +++ b/backend/src/entities/email/email/email.service.ts @@ -18,285 +18,285 @@ import { EmailGenerator } from './email.generator.js'; import { IMessage } from './email.interface.js'; export interface ICronMessagingResults { - messageId?: string; - accepted?: Array; - rejected?: Array; + messageId?: string; + accepted?: Array; + rejected?: Array; } @Injectable() export class EmailService { - private readonly emailFrom = getProcessVariable('EMAIL_FROM') || Constants.AUTOADMIN_SUPPORT_MAIL; - constructor( - @Inject(BaseType.NUNJUCKS) - private readonly nunjucksEnv: nunjucks.Environment, - private readonly emailTransporterService: EmailTransporterService, - private readonly logger: WinstonLogger, - ) {} + private readonly emailFrom = getProcessVariable('EMAIL_FROM') || Constants.AUTOADMIN_SUPPORT_MAIL; + constructor( + @Inject(BaseType.NUNJUCKS) + private readonly nunjucksEnv: nunjucks.Environment, + private readonly emailTransporterService: EmailTransporterService, + private readonly logger: WinstonLogger, + ) {} - public async sendEmailToUser(letterContent: IMessage): Promise { - if (process.env.NODE_ENV === 'test') return; - const mailResult = await this.sendEmailWithTimeout(letterContent); - if (mailResult) { - return mailResult; - } - } + public async sendEmailToUser(letterContent: IMessage): Promise { + if (process.env.NODE_ENV === 'test') return; + const mailResult = await this.sendEmailWithTimeout(letterContent); + if (mailResult) { + return mailResult; + } + } - public async sendEmailActionToUser( - userEmail: string, - userInfo: UserInfoMessageData, - triggerOperation: TableActionEventEnum, - tableName: string, - primaryKeyValuesArray: Array>, - ): Promise { - const currentYear = new Date().getFullYear(); - const action = - triggerOperation === TableActionEventEnum.ADD_ROW - ? 'added a row' - : triggerOperation === TableActionEventEnum.UPDATE_ROW - ? 'updated a row' - : triggerOperation === TableActionEventEnum.DELETE_ROW - ? 'deleted a row' - : 'performed an action'; - const textContent = EMAIL_TEXT.ACTION_EMAIL.EMAIL_TEXT(userInfo, action, tableName, primaryKeyValuesArray); + public async sendEmailActionToUser( + userEmail: string, + userInfo: UserInfoMessageData, + triggerOperation: TableActionEventEnum, + tableName: string, + primaryKeyValuesArray: Array>, + ): Promise { + const currentYear = new Date().getFullYear(); + const action = + triggerOperation === TableActionEventEnum.ADD_ROW + ? 'added a row' + : triggerOperation === TableActionEventEnum.UPDATE_ROW + ? 'updated a row' + : triggerOperation === TableActionEventEnum.DELETE_ROW + ? 'deleted a row' + : 'performed an action'; + const textContent = EMAIL_TEXT.ACTION_EMAIL.EMAIL_TEXT(userInfo, action, tableName, primaryKeyValuesArray); - const primaryKeysValuesStr = JSON.stringify(primaryKeyValuesArray); - const letterContent: IMessage = { - from: this.emailFrom, - to: userEmail, - subject: EMAIL_TEXT.ACTION_EMAIL.EMAIL_SUBJECT, - text: textContent, - html: this.nunjucksEnv.render('action-email-activation.njk', { - userInfo, - triggerOperation, - tableName, - action, - primaryKeysValuesStr, - currentYear, - textContent, - primaryKeyValuesArray, - }), - }; - return await this.sendEmailToUser(letterContent); - } + const primaryKeysValuesStr = JSON.stringify(primaryKeyValuesArray); + const letterContent: IMessage = { + from: this.emailFrom, + to: userEmail, + subject: EMAIL_TEXT.ACTION_EMAIL.EMAIL_SUBJECT, + text: textContent, + html: this.nunjucksEnv.render('action-email-activation.njk', { + userInfo, + triggerOperation, + tableName, + action, + primaryKeysValuesStr, + currentYear, + textContent, + primaryKeyValuesArray, + }), + }; + return await this.sendEmailToUser(letterContent); + } - public async sendRemindersToUsers(userEmails: Array): Promise> { - const queue = new PQueue({ concurrency: 3 }); + public async sendRemindersToUsers(userEmails: Array): Promise> { + const queue = new PQueue({ concurrency: 3 }); - const mailingResults: Array = []; + const mailingResults: Array = []; - for (const email of userEmails) { - try { - const result = await queue.add(async () => { - return await this.sendReminderToUser(email); - }); - mailingResults.push(result); - } catch (error) { - this.logger.error(`Failed to send reminder to ${email}: ${error.message}`); - Sentry.captureException(error); - mailingResults.push(null); - } - } + for (const email of userEmails) { + try { + const result = await queue.add(async () => { + return await this.sendReminderToUser(email); + }); + mailingResults.push(result); + } catch (error) { + this.logger.error(`Failed to send reminder to ${email}: ${error.message}`); + Sentry.captureException(error); + mailingResults.push(null); + } + } - await queue.onIdle(); + await queue.onIdle(); - return this.buildMailingResults(mailingResults); - } + return this.buildMailingResults(mailingResults); + } - public async send2faEnabledInCompany( - userEmails: Array, - companyName: string, - ): Promise> { - try { - const queue = new PQueue({ concurrency: 3 }); + public async send2faEnabledInCompany( + userEmails: Array, + companyName: string, + ): Promise> { + try { + const queue = new PQueue({ concurrency: 3 }); - const mailingResults: Array = await Promise.all( - userEmails.map(async (email: string) => { - return await queue.add(async () => { - return await this.send2faEnabledInCompanyToUser(email, companyName); - }); - }), - ); - return mailingResults; - } catch (error) { - this.logger.error(error); - } - } + const mailingResults: Array = await Promise.all( + userEmails.map(async (email: string) => { + return await queue.add(async () => { + return await this.send2faEnabledInCompanyToUser(email, companyName); + }); + }), + ); + return mailingResults; + } catch (error) { + this.logger.error(error); + } + } - public async sendInvitedInNewGroup(email: string, groupTitle: string): Promise { - const currentYear = new Date().getFullYear(); - const letterContent: IMessage = { - from: this.emailFrom, - to: email, - subject: EMAIL_TEXT.INVITE_IN_GROUP.EMAIL_SUBJECT, - text: EMAIL_TEXT.INVITE_IN_GROUP.EMAIL_TEXT(groupTitle), - html: this.nunjucksEnv.render('invite-in-group-notification.njk', { - groupTitle, - currentYear, - }), - }; - return await this.sendEmailToUser(letterContent); - } + public async sendInvitedInNewGroup(email: string, groupTitle: string): Promise { + const currentYear = new Date().getFullYear(); + const letterContent: IMessage = { + from: this.emailFrom, + to: email, + subject: EMAIL_TEXT.INVITE_IN_GROUP.EMAIL_SUBJECT, + text: EMAIL_TEXT.INVITE_IN_GROUP.EMAIL_TEXT(groupTitle), + html: this.nunjucksEnv.render('invite-in-group-notification.njk', { + groupTitle, + currentYear, + }), + }; + return await this.sendEmailToUser(letterContent); + } - public async sendInvitationToCompany( - email: string, - verificationString: string, - companyId: string, - invitedCompanyName: string, - customCompanyDomain: string | null, - ): Promise { - const currentYear = new Date().getFullYear(); - const domain = customCompanyDomain ? customCompanyDomain : Constants.APP_DOMAIN_ADDRESS; - const link = `${domain}/company/${companyId}/verify/${verificationString}/`; - const companyName = invitedCompanyName ? ` "${invitedCompanyName}" ` : ` `; - const letterContent: IMessage = { - from: this.emailFrom, - to: email, - subject: EMAIL_TEXT.INVITE_IN_COMPANY.EMAIL_SUBJECT, - text: EMAIL_TEXT.INVITE_IN_COMPANY.EMAIL_TEXT(link, escapeHtml(companyName)), - html: this.nunjucksEnv.render('invite-in-company-notification.njk', { - linkToAccept: link, - companyName, - currentYear, - }), - }; - return await this.sendEmailToUser(letterContent); - } + public async sendInvitationToCompany( + email: string, + verificationString: string, + companyId: string, + invitedCompanyName: string, + customCompanyDomain: string | null, + ): Promise { + const currentYear = new Date().getFullYear(); + const domain = customCompanyDomain ? customCompanyDomain : Constants.APP_DOMAIN_ADDRESS; + const link = `${domain}/company/${companyId}/verify/${verificationString}/`; + const companyName = invitedCompanyName ? ` "${invitedCompanyName}" ` : ` `; + const letterContent: IMessage = { + from: this.emailFrom, + to: email, + subject: EMAIL_TEXT.INVITE_IN_COMPANY.EMAIL_SUBJECT, + text: EMAIL_TEXT.INVITE_IN_COMPANY.EMAIL_TEXT(link, escapeHtml(companyName)), + html: this.nunjucksEnv.render('invite-in-company-notification.njk', { + linkToAccept: link, + companyName, + currentYear, + }), + }; + return await this.sendEmailToUser(letterContent); + } - public async sendEmailConfirmation( - email: string, - verificationString: string, - customCompanyDomain: string | null, - ): Promise { - const domain = customCompanyDomain ? customCompanyDomain : Constants.APP_DOMAIN_ADDRESS; - const link = `${domain}/external/user/email/verify/${verificationString}`; - const currentYear = new Date().getFullYear(); - const letterContent: IMessage = { - from: this.emailFrom, - to: email, - subject: EMAIL_TEXT.CONFIRM_EMAIL.EMAIL_SUBJECT, - text: EMAIL_TEXT.CONFIRM_EMAIL.EMAIL_TEXT(link), - html: this.nunjucksEnv.render('confirm-email-notification.njk', { linkToConfirm: link, currentYear }), - }; - return await this.sendEmailToUser(letterContent); - } + public async sendEmailConfirmation( + email: string, + verificationString: string, + customCompanyDomain: string | null, + ): Promise { + const domain = customCompanyDomain ? customCompanyDomain : Constants.APP_DOMAIN_ADDRESS; + const link = `${domain}/external/user/email/verify/${verificationString}`; + const currentYear = new Date().getFullYear(); + const letterContent: IMessage = { + from: this.emailFrom, + to: email, + subject: EMAIL_TEXT.CONFIRM_EMAIL.EMAIL_SUBJECT, + text: EMAIL_TEXT.CONFIRM_EMAIL.EMAIL_TEXT(link), + html: this.nunjucksEnv.render('confirm-email-notification.njk', { linkToConfirm: link, currentYear }), + }; + return await this.sendEmailToUser(letterContent); + } - public async sendEmailChanged(email: string): Promise { - const currentYear = new Date().getFullYear(); - const letterContent: IMessage = { - from: this.emailFrom, - to: email, - subject: EMAIL_TEXT.CHANGED_EMAIL.EMAIL_SUBJECT, - text: EMAIL_TEXT.CHANGED_EMAIL.EMAIL_TEXT, - html: this.nunjucksEnv.render('changed-email-notification.njk', { currentYear }), - }; - return await this.sendEmailToUser(letterContent); - } + public async sendEmailChanged(email: string): Promise { + const currentYear = new Date().getFullYear(); + const letterContent: IMessage = { + from: this.emailFrom, + to: email, + subject: EMAIL_TEXT.CHANGED_EMAIL.EMAIL_SUBJECT, + text: EMAIL_TEXT.CHANGED_EMAIL.EMAIL_TEXT, + html: this.nunjucksEnv.render('changed-email-notification.njk', { currentYear }), + }; + return await this.sendEmailToUser(letterContent); + } - public async sendEmailChangeRequest( - email: string, - requestString: string, - customCompanyDomain: string | null, - ): Promise { - const currentYear = new Date().getFullYear(); - const domain = customCompanyDomain ? customCompanyDomain : Constants.APP_DOMAIN_ADDRESS; - const linkToConfirm = `${domain}/external/user/email/change/verify/${requestString}`; - const letterContent: IMessage = { - from: this.emailFrom, - to: email, - subject: EMAIL_TEXT.CHANGE_EMAIL_REQUEST.EMAIL_SUBJECT, - text: EMAIL_TEXT.CHANGE_EMAIL_REQUEST.EMAIL_TEXT(linkToConfirm), - html: this.nunjucksEnv.render('change-email-request-notification.njk', { linkToConfirm, currentYear }), - }; - return await this.sendEmailToUser(letterContent); - } + public async sendEmailChangeRequest( + email: string, + requestString: string, + customCompanyDomain: string | null, + ): Promise { + const currentYear = new Date().getFullYear(); + const domain = customCompanyDomain ? customCompanyDomain : Constants.APP_DOMAIN_ADDRESS; + const linkToConfirm = `${domain}/external/user/email/change/verify/${requestString}`; + const letterContent: IMessage = { + from: this.emailFrom, + to: email, + subject: EMAIL_TEXT.CHANGE_EMAIL_REQUEST.EMAIL_SUBJECT, + text: EMAIL_TEXT.CHANGE_EMAIL_REQUEST.EMAIL_TEXT(linkToConfirm), + html: this.nunjucksEnv.render('change-email-request-notification.njk', { linkToConfirm, currentYear }), + }; + return await this.sendEmailToUser(letterContent); + } - public async sendPasswordResetRequest( - email: string, - requestString: string, - customCompanyDomain: string | null, - ): Promise { - const currentYear = new Date().getFullYear(); - const domain = customCompanyDomain ? customCompanyDomain : Constants.APP_DOMAIN_ADDRESS; - const linkToConfirm = `${domain}/external/user/password/reset/verify/${requestString}`; - const letterContent: IMessage = { - from: this.emailFrom, - to: email, - subject: EMAIL_TEXT.RESET_PASSWORD_REQUEST.EMAIL_SUBJECT, - text: EMAIL_TEXT.RESET_PASSWORD_REQUEST.EMAIL_TEXT(linkToConfirm), - html: this.nunjucksEnv.render('reset-password-request-notification.njk', { linkToConfirm, currentYear }), - }; - return await this.sendEmailToUser(letterContent); - } + public async sendPasswordResetRequest( + email: string, + requestString: string, + customCompanyDomain: string | null, + ): Promise { + const currentYear = new Date().getFullYear(); + const domain = customCompanyDomain ? customCompanyDomain : Constants.APP_DOMAIN_ADDRESS; + const linkToConfirm = `${domain}/external/user/password/reset/verify/${requestString}`; + const letterContent: IMessage = { + from: this.emailFrom, + to: email, + subject: EMAIL_TEXT.RESET_PASSWORD_REQUEST.EMAIL_SUBJECT, + text: EMAIL_TEXT.RESET_PASSWORD_REQUEST.EMAIL_TEXT(linkToConfirm), + html: this.nunjucksEnv.render('reset-password-request-notification.njk', { linkToConfirm, currentYear }), + }; + return await this.sendEmailToUser(letterContent); + } - public async sendMail(letterContent: IMessage): Promise { - const testEmail = new EmailLetter({ - from: letterContent.from, - to: letterContent.to, - subject: letterContent.subject, - text: letterContent.text, - html: letterContent.html, - }); - const emailGenerator = new EmailGenerator(); - const emailMessage = emailGenerator.generateEmail(testEmail); - return await this.emailTransporterService.transportEmail(emailMessage); - } + public async sendMail(letterContent: IMessage): Promise { + const testEmail = new EmailLetter({ + from: letterContent.from, + to: letterContent.to, + subject: letterContent.subject, + text: letterContent.text, + html: letterContent.html, + }); + const emailGenerator = new EmailGenerator(); + const emailMessage = emailGenerator.generateEmail(testEmail); + return await this.emailTransporterService.transportEmail(emailMessage); + } - private async sendReminderToUser(email: string): Promise { - const letterContent: IMessage = { - from: this.emailFrom, - to: email, - subject: EMAIL_TEXT.ROCKETADMIN_REMINDER.EMAIL_SUBJECT, - text: EMAIL_TEXT.ROCKETADMIN_REMINDER.EMAIL_TEXT, - html: this.nunjucksEnv.render('rocketadmin-reminder-email.html'), - }; - return await this.sendEmailToUser(letterContent); - } + private async sendReminderToUser(email: string): Promise { + const letterContent: IMessage = { + from: this.emailFrom, + to: email, + subject: EMAIL_TEXT.ROCKETADMIN_REMINDER.EMAIL_SUBJECT, + text: EMAIL_TEXT.ROCKETADMIN_REMINDER.EMAIL_TEXT, + html: this.nunjucksEnv.render('rocketadmin-reminder-email.html'), + }; + return await this.sendEmailToUser(letterContent); + } - private async send2faEnabledInCompanyToUser( - email: string, - companyName: string, - ): Promise { - const letterContent: IMessage = { - from: this.emailFrom, - to: email, - subject: EMAIL_TEXT.COMPANY_2FA_ENABLED.EMAIL_SUBJECT, - text: EMAIL_TEXT.COMPANY_2FA_ENABLED.EMAIL_TEXT(companyName), - html: this.nunjucksEnv.render('company-2fa-enabled-notification.njk', { - companyName, - }), - }; - return await this.sendEmailToUser(letterContent); - } + private async send2faEnabledInCompanyToUser( + email: string, + companyName: string, + ): Promise { + const letterContent: IMessage = { + from: this.emailFrom, + to: email, + subject: EMAIL_TEXT.COMPANY_2FA_ENABLED.EMAIL_SUBJECT, + text: EMAIL_TEXT.COMPANY_2FA_ENABLED.EMAIL_TEXT(companyName), + html: this.nunjucksEnv.render('company-2fa-enabled-notification.njk', { + companyName, + }), + }; + return await this.sendEmailToUser(letterContent); + } - private async sendEmailWithTimeout(letterContent: IMessage): Promise { - return new Promise(async (resolve) => { - setTimeout(() => { - resolve(null); - }, 4000); - try { - const mailResult = await this.sendMail(letterContent); - resolve(mailResult); - } catch (e) { - Sentry.captureException(e); - console.error(e); - resolve(null); - } - }); - } + private async sendEmailWithTimeout(letterContent: IMessage): Promise { + return new Promise(async (resolve) => { + setTimeout(() => { + resolve(null); + }, 4000); + try { + const mailResult = await this.sendMail(letterContent); + resolve(mailResult); + } catch (e) { + Sentry.captureException(e); + console.error(e); + resolve(null); + } + }); + } - private buildMailingResults( - results: Array, - ): Array { - return results.map((result) => { - if (!result) { - return null; - } - const { messageId, accepted, rejected } = result; - return { - messageId: messageId ? messageId : undefined, - accepted: accepted ? accepted : undefined, - rejected: rejected ? rejected : undefined, - }; - }); - } + private buildMailingResults( + results: Array, + ): Array { + return results.map((result) => { + if (!result) { + return null; + } + const { messageId, accepted, rejected } = result; + return { + messageId: messageId ? messageId : undefined, + accepted: accepted ? accepted : undefined, + rejected: rejected ? rejected : undefined, + }; + }); + } } diff --git a/backend/src/entities/email/repository/email-verification.repository.interface.ts b/backend/src/entities/email/repository/email-verification.repository.interface.ts index 664b711fe..c8e3f3a63 100644 --- a/backend/src/entities/email/repository/email-verification.repository.interface.ts +++ b/backend/src/entities/email/repository/email-verification.repository.interface.ts @@ -1,5 +1,5 @@ -import { EmailVerificationEntity } from '../email-verification.entity.js'; import { UserEntity } from '../../user/user.entity.js'; +import { EmailVerificationEntity } from '../email-verification.entity.js'; export interface IEmailVerificationRepository { findVerificationWithVerificationString(verificationString: string): Promise; diff --git a/backend/src/entities/email/template-engine/nunjucks.module.ts b/backend/src/entities/email/template-engine/nunjucks.module.ts index f1179e750..da59f6a34 100644 --- a/backend/src/entities/email/template-engine/nunjucks.module.ts +++ b/backend/src/entities/email/template-engine/nunjucks.module.ts @@ -1,10 +1,11 @@ -import { Module, Global } from '@nestjs/common'; +import { existsSync } from 'node:fs'; +import { Global, Module } from '@nestjs/common'; +import assert from 'assert'; import * as nunjucks from 'nunjucks'; -import { BaseType } from '../../../common/data-injection.tokens.js'; import path from 'path'; import { fileURLToPath } from 'url'; -import { existsSync } from 'node:fs'; -import assert from 'assert'; +import { BaseType } from '../../../common/data-injection.tokens.js'; + const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -13,15 +14,15 @@ assert(existsSync(pathToTemplates), `Email templates directory does not exist: $ @Global() @Module({ - providers: [ - { - provide: BaseType.NUNJUCKS, - useFactory: () => { - const env = new nunjucks.Environment(new nunjucks.FileSystemLoader(pathToTemplates)); - return env; - }, - }, - ], - exports: [BaseType.NUNJUCKS], + providers: [ + { + provide: BaseType.NUNJUCKS, + useFactory: () => { + const env = new nunjucks.Environment(new nunjucks.FileSystemLoader(pathToTemplates)); + return env; + }, + }, + ], + exports: [BaseType.NUNJUCKS], }) export class NunjucksModule {} diff --git a/backend/src/entities/email/transporter/email-transporter-service.ts b/backend/src/entities/email/transporter/email-transporter-service.ts index 8a9119633..148ff549d 100644 --- a/backend/src/entities/email/transporter/email-transporter-service.ts +++ b/backend/src/entities/email/transporter/email-transporter-service.ts @@ -1,35 +1,35 @@ +import { Injectable } from '@nestjs/common'; import nodemailer from 'nodemailer'; import SMTPTransport from 'nodemailer/lib/smtp-transport'; +import { isSaaS } from '../../../helpers/app/is-saas.js'; import { IMessage } from '../email/email.interface.js'; import { EmailConfigService } from '../email-config/email-config.service.js'; import { IEmailTransporterInterface } from './email-transporter.interface.js'; -import { Injectable } from '@nestjs/common'; -import { isSaaS } from '../../../helpers/app/is-saas.js'; @Injectable() export class EmailTransporterService implements IEmailTransporterInterface { - private transporter: nodemailer.Transporter; - constructor(private readonly emailConfigService: EmailConfigService) { - this.transporter = this.createTransporter(); - } + private transporter: nodemailer.Transporter; + constructor(private readonly emailConfigService: EmailConfigService) { + this.transporter = this.createTransporter(); + } - public async transportEmail(mail: IMessage): Promise { - const formattedFrom = isSaaS() ? this.formatEmailAddress(mail.from) : mail.from; - return await this.transporter.sendMail({ - from: formattedFrom, - to: mail.to, - subject: mail.subject, - text: mail.text, - html: mail.html, - }); - } + public async transportEmail(mail: IMessage): Promise { + const formattedFrom = isSaaS() ? this.formatEmailAddress(mail.from) : mail.from; + return await this.transporter.sendMail({ + from: formattedFrom, + to: mail.to, + subject: mail.subject, + text: mail.text, + html: mail.html, + }); + } - private createTransporter(): nodemailer.Transporter { - const transportConfig = this.emailConfigService.getEmailServiceConfig(); - return nodemailer.createTransport(transportConfig); - } + private createTransporter(): nodemailer.Transporter { + const transportConfig = this.emailConfigService.getEmailServiceConfig(); + return nodemailer.createTransport(transportConfig); + } - private formatEmailAddress(email: string): string { - const defaultName = 'Rocketadmin.com'; - return `${defaultName} <${email}>`; - } + private formatEmailAddress(email: string): string { + const defaultName = 'Rocketadmin.com'; + return `${defaultName} <${email}>`; + } } diff --git a/backend/src/entities/email/transporter/email-transporter.interface.ts b/backend/src/entities/email/transporter/email-transporter.interface.ts index e1610d7ad..1159b550a 100644 --- a/backend/src/entities/email/transporter/email-transporter.interface.ts +++ b/backend/src/entities/email/transporter/email-transporter.interface.ts @@ -1,6 +1,6 @@ -import { IMessage } from '../email/email.interface.js'; import SMTPTransport from 'nodemailer/lib/smtp-transport'; +import { IMessage } from '../email/email.interface.js'; export interface IEmailTransporterInterface { - transportEmail(mail: IMessage): Promise; + transportEmail(mail: IMessage): Promise; } diff --git a/backend/src/entities/email/utils/escape-html.util.ts b/backend/src/entities/email/utils/escape-html.util.ts index 1c2fa2f1c..e4f29c4bf 100644 --- a/backend/src/entities/email/utils/escape-html.util.ts +++ b/backend/src/entities/email/utils/escape-html.util.ts @@ -1,9 +1,8 @@ export function escapeHtml(unsafe: string): string { - return unsafe - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"') - .replace(/'/g, '''); + return unsafe + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); } - diff --git a/backend/src/entities/group/application/data-sctructures/add-user-in-group.ds.ts b/backend/src/entities/group/application/data-sctructures/add-user-in-group.ds.ts index cd01b1b14..d807db5b8 100644 --- a/backend/src/entities/group/application/data-sctructures/add-user-in-group.ds.ts +++ b/backend/src/entities/group/application/data-sctructures/add-user-in-group.ds.ts @@ -1,14 +1,14 @@ export class AddUserInGroupDs { - email: string; - groupId: string; - companyId?: string; - userSaasRole?: string; + email: string; + groupId: string; + companyId?: string; + userSaasRole?: string; } export class AddUserInGroupWithSaaSDs { - email: string; - groupId: string; - companyId: string; - userSaasRole: string; - inviterId: string; + email: string; + groupId: string; + companyId: string; + userSaasRole: string; + inviterId: string; } diff --git a/backend/src/entities/group/application/data-sctructures/added-user-in-group.ds.ts b/backend/src/entities/group/application/data-sctructures/added-user-in-group.ds.ts index a82e53926..2116227a9 100644 --- a/backend/src/entities/group/application/data-sctructures/added-user-in-group.ds.ts +++ b/backend/src/entities/group/application/data-sctructures/added-user-in-group.ds.ts @@ -2,12 +2,12 @@ import { ApiProperty } from '@nestjs/swagger'; import { FoundGroupResponseDto } from '../../dto/found-group-response.dto.js'; export class AddedUserInGroupDs { - @ApiProperty() - group: FoundGroupResponseDto; + @ApiProperty() + group: FoundGroupResponseDto; - @ApiProperty() - message: string; + @ApiProperty() + message: string; - @ApiProperty() - external_invite: boolean; + @ApiProperty() + external_invite: boolean; } diff --git a/backend/src/entities/group/application/data-sctructures/deleted-group-result.ds.ts b/backend/src/entities/group/application/data-sctructures/deleted-group-result.ds.ts index 2f31f54f3..03349ad89 100644 --- a/backend/src/entities/group/application/data-sctructures/deleted-group-result.ds.ts +++ b/backend/src/entities/group/application/data-sctructures/deleted-group-result.ds.ts @@ -1,12 +1,12 @@ import { ApiProperty } from '@nestjs/swagger'; export class DeletedGroupResultDs { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - title: string; + @ApiProperty() + title: string; - @ApiProperty() - isMain: boolean; + @ApiProperty() + isMain: boolean; } diff --git a/backend/src/entities/group/application/data-sctructures/found-user-groups.ds.ts b/backend/src/entities/group/application/data-sctructures/found-user-groups.ds.ts index a85350fd8..7a17616bc 100644 --- a/backend/src/entities/group/application/data-sctructures/found-user-groups.ds.ts +++ b/backend/src/entities/group/application/data-sctructures/found-user-groups.ds.ts @@ -3,33 +3,33 @@ import { AccessLevelEnum } from '../../../../enums/index.js'; import { SimpleFoundUserInfoDs } from '../../../user/dto/found-user.dto.js'; export class FoundGroupDataInfoDs { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - title: string; + @ApiProperty() + title: string; - @ApiProperty() - isMain: boolean; + @ApiProperty() + isMain: boolean; } export class FoundGroupDataWithUsersDs extends FoundGroupDataInfoDs { - @ApiProperty({ isArray: true }) - users: Array; + @ApiProperty({ isArray: true }) + users: Array; } export class FoundGroupDataWithAccessLevelDs { - @ApiProperty() - group: FoundGroupDataInfoDs; + @ApiProperty() + group: FoundGroupDataInfoDs; - @ApiProperty({ enum: AccessLevelEnum }) - accessLevel: AccessLevelEnum; + @ApiProperty({ enum: AccessLevelEnum }) + accessLevel: AccessLevelEnum; } export class FoundUserGroupsDs { - @ApiProperty({ isArray: true, type: FoundGroupDataWithAccessLevelDs }) - groups: Array; + @ApiProperty({ isArray: true, type: FoundGroupDataWithAccessLevelDs }) + groups: Array; - @ApiProperty() - groupsCount: number; + @ApiProperty() + groupsCount: number; } diff --git a/backend/src/entities/group/application/data-sctructures/remove-user-from-group-result.ds.ts b/backend/src/entities/group/application/data-sctructures/remove-user-from-group-result.ds.ts index 7355e7c6d..1e7dffe94 100644 --- a/backend/src/entities/group/application/data-sctructures/remove-user-from-group-result.ds.ts +++ b/backend/src/entities/group/application/data-sctructures/remove-user-from-group-result.ds.ts @@ -1,29 +1,29 @@ import { ApiProperty } from '@nestjs/swagger'; export class UsersInGroupInfoDS { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - email: string; + @ApiProperty() + email: string; - @ApiProperty() - createdAt: Date; + @ApiProperty() + createdAt: Date; - @ApiProperty() - isActive: boolean; + @ApiProperty() + isActive: boolean; } export class RemoveUserFromGroupResultDs { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - title: string; + @ApiProperty() + title: string; - @ApiProperty() - isMain: boolean; + @ApiProperty() + isMain: boolean; - @ApiProperty({ isArray: true, type: UsersInGroupInfoDS }) - users: Array; + @ApiProperty({ isArray: true, type: UsersInGroupInfoDS }) + users: Array; } diff --git a/backend/src/entities/group/dto/add-user-ingroup-dto.ts b/backend/src/entities/group/dto/add-user-ingroup-dto.ts index 380da35b7..35b1187e6 100644 --- a/backend/src/entities/group/dto/add-user-ingroup-dto.ts +++ b/backend/src/entities/group/dto/add-user-ingroup-dto.ts @@ -1,30 +1,30 @@ import { ApiProperty } from '@nestjs/swagger'; -import { UserRoleEnum } from '../../user/enums/user-role.enum.js'; import { IsEmail, IsEnum, IsNotEmpty, IsOptional, IsString, IsUUID } from 'class-validator'; +import { UserRoleEnum } from '../../user/enums/user-role.enum.js'; export class AddUserInGroupDto { - @ApiProperty() - @IsString() - @IsNotEmpty() - @IsEmail() - email: string; + @ApiProperty() + @IsString() + @IsNotEmpty() + @IsEmail() + email: string; - @ApiProperty() - @IsString() - @IsNotEmpty() - @IsUUID() - groupId: string; + @ApiProperty() + @IsString() + @IsNotEmpty() + @IsUUID() + groupId: string; - @ApiProperty() - @IsOptional() - @IsNotEmpty() - @IsString() - @IsUUID() - companyId: string; + @ApiProperty() + @IsOptional() + @IsNotEmpty() + @IsString() + @IsUUID() + companyId: string; - @ApiProperty({ enum: UserRoleEnum }) - @IsOptional() - @IsNotEmpty() - @IsEnum(UserRoleEnum) - role: UserRoleEnum; + @ApiProperty({ enum: UserRoleEnum }) + @IsOptional() + @IsNotEmpty() + @IsEnum(UserRoleEnum) + role: UserRoleEnum; } diff --git a/backend/src/entities/group/dto/delete-user-from-group-dto.ts b/backend/src/entities/group/dto/delete-user-from-group-dto.ts index b16a6a8d1..62245164f 100644 --- a/backend/src/entities/group/dto/delete-user-from-group-dto.ts +++ b/backend/src/entities/group/dto/delete-user-from-group-dto.ts @@ -2,15 +2,15 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsEmail, IsNotEmpty, IsString, IsUUID } from 'class-validator'; export class DeleteUserFromGroupDTO { - @ApiProperty() - @IsString() - @IsEmail() - @IsNotEmpty() - email: string; + @ApiProperty() + @IsString() + @IsEmail() + @IsNotEmpty() + email: string; - @IsString() - @IsNotEmpty() - @IsUUID() - @ApiProperty() - groupId: string; + @IsString() + @IsNotEmpty() + @IsUUID() + @ApiProperty() + groupId: string; } diff --git a/backend/src/entities/group/dto/found-group-response.dto.ts b/backend/src/entities/group/dto/found-group-response.dto.ts index 839b34c91..2ce125525 100644 --- a/backend/src/entities/group/dto/found-group-response.dto.ts +++ b/backend/src/entities/group/dto/found-group-response.dto.ts @@ -2,15 +2,15 @@ import { ApiProperty } from '@nestjs/swagger'; import { SimpleFoundUserInfoDs } from '../../user/dto/found-user.dto.js'; export class FoundGroupResponseDto { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - title: string; + @ApiProperty() + title: string; - @ApiProperty() - isMain: boolean; + @ApiProperty() + isMain: boolean; - @ApiProperty({ required: false, isArray: true, type: SimpleFoundUserInfoDs }) - users?: Array; + @ApiProperty({ required: false, isArray: true, type: SimpleFoundUserInfoDs }) + users?: Array; } diff --git a/backend/src/entities/group/dto/update-group-title.dto.ts b/backend/src/entities/group/dto/update-group-title.dto.ts index f6e559159..d23237f41 100644 --- a/backend/src/entities/group/dto/update-group-title.dto.ts +++ b/backend/src/entities/group/dto/update-group-title.dto.ts @@ -2,14 +2,14 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty, IsString, IsUUID } from 'class-validator'; export class UpdateGroupTitleDto { - @ApiProperty() - @IsString() - @IsNotEmpty() - title: string; + @ApiProperty() + @IsString() + @IsNotEmpty() + title: string; - @ApiProperty() - @IsString() - @IsNotEmpty() - @IsUUID() - groupId: string; + @ApiProperty() + @IsString() + @IsNotEmpty() + @IsUUID() + groupId: string; } diff --git a/backend/src/entities/group/group.controller.ts b/backend/src/entities/group/group.controller.ts index 041abbd50..f6dc23745 100644 --- a/backend/src/entities/group/group.controller.ts +++ b/backend/src/entities/group/group.controller.ts @@ -14,6 +14,7 @@ import { import { ApiBearerAuth, ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import { UseCaseType } from '../../common/data-injection.tokens.js'; import { SlugUuid, UserId } from '../../decorators/index.js'; +import { Timeout } from '../../decorators/timeout.decorator.js'; import { AmplitudeEventTypeEnum, InTransactionEnum } from '../../enums/index.js'; import { Messages } from '../../exceptions/text/messages.js'; import { GroupEditGuard, GroupReadGuard } from '../../guards/index.js'; @@ -37,7 +38,6 @@ import { IRemoveUserFromGroup, IUpdateGroupTitle, } from './use-cases/use-cases.interfaces.js'; -import { Timeout } from '../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/group/group.entity.ts b/backend/src/entities/group/group.entity.ts index 800e80c10..bd4f1a98c 100644 --- a/backend/src/entities/group/group.entity.ts +++ b/backend/src/entities/group/group.entity.ts @@ -1,33 +1,45 @@ import { Column, Entity, JoinColumn, ManyToMany, ManyToOne, PrimaryGeneratedColumn, Relation, Unique } from 'typeorm'; -import { UserEntity } from '../user/user.entity.js'; -import { PermissionEntity } from '../permission/permission.entity.js'; import { ConnectionEntity } from '../connection/connection.entity.js'; +import { PermissionEntity } from '../permission/permission.entity.js'; +import { UserEntity } from '../user/user.entity.js'; @Entity('group') @Unique(['connection', 'title']) export class GroupEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column() - title: string; + @Column() + title: string; - @Column({ default: false, type: 'boolean' }) - isMain: boolean; + @Column({ default: false, type: 'boolean' }) + isMain: boolean; - @ManyToMany((_) => PermissionEntity, (permission) => permission.groups, { - onDelete: 'CASCADE', - }) - permissions?: Relation[]; + @ManyToMany( + (_) => PermissionEntity, + (permission) => permission.groups, + { + onDelete: 'CASCADE', + }, + ) + permissions?: Relation[]; - @ManyToMany((_) => UserEntity, (user) => user.groups, { - onDelete: 'CASCADE', - }) - users?: Relation[]; + @ManyToMany( + (_) => UserEntity, + (user) => user.groups, + { + onDelete: 'CASCADE', + }, + ) + users?: Relation[]; - @ManyToOne((_) => ConnectionEntity, (connection) => connection.groups, { - onDelete: 'CASCADE', - }) - @JoinColumn() - connection: Relation; + @ManyToOne( + (_) => ConnectionEntity, + (connection) => connection.groups, + { + onDelete: 'CASCADE', + }, + ) + @JoinColumn() + connection: Relation; } diff --git a/backend/src/entities/group/group.module.ts b/backend/src/entities/group/group.module.ts index 4d4b01fcb..31efe8d32 100644 --- a/backend/src/entities/group/group.module.ts +++ b/backend/src/entities/group/group.module.ts @@ -20,66 +20,66 @@ import { AddUserInGroupUseCase } from './use-cases/saas-add-user-in-group-v2.use import { UpdateGroupTitleUseCase } from './use-cases/update-group-title.use.case.js'; @Module({ - imports: [ - TypeOrmModule.forFeature([ - ConnectionEntity, - GroupEntity, - PermissionEntity, - UserEntity, - TableSettingsEntity, - LogOutEntity, - ]), - UserModule, - AgentModule, - ], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.INVITE_USER_IN_GROUP, - useClass: AddUserInGroupUseCase, - }, - { - provide: UseCaseType.FIND_ALL_USER_GROUPS, - useClass: FindAllUserGroupsUseCase, - }, - { - provide: UseCaseType.FIND_ALL_USERS_IN_GROUP, - useClass: FindAllUsersInGroupUseCase, - }, - { - provide: UseCaseType.REMOVE_USER_FROM_GROUP, - useClass: RemoveUserFromGroupUseCase, - }, - { - provide: UseCaseType.DELETE_GROUP, - useClass: DeleteGroupUseCase, - }, - { - provide: UseCaseType.UPDATE_GROUP_TITLE, - useClass: UpdateGroupTitleUseCase, - }, - ], - controllers: [GroupController], - exports: [], + imports: [ + TypeOrmModule.forFeature([ + ConnectionEntity, + GroupEntity, + PermissionEntity, + UserEntity, + TableSettingsEntity, + LogOutEntity, + ]), + UserModule, + AgentModule, + ], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.INVITE_USER_IN_GROUP, + useClass: AddUserInGroupUseCase, + }, + { + provide: UseCaseType.FIND_ALL_USER_GROUPS, + useClass: FindAllUserGroupsUseCase, + }, + { + provide: UseCaseType.FIND_ALL_USERS_IN_GROUP, + useClass: FindAllUsersInGroupUseCase, + }, + { + provide: UseCaseType.REMOVE_USER_FROM_GROUP, + useClass: RemoveUserFromGroupUseCase, + }, + { + provide: UseCaseType.DELETE_GROUP, + useClass: DeleteGroupUseCase, + }, + { + provide: UseCaseType.UPDATE_GROUP_TITLE, + useClass: UpdateGroupTitleUseCase, + }, + ], + controllers: [GroupController], + exports: [], }) export class GroupModule { - public configure(consumer: MiddlewareConsumer): any { - consumer - .apply(AuthMiddleware) - .forRoutes( - { path: 'groups', method: RequestMethod.GET }, - { path: 'group', method: RequestMethod.POST }, - { path: 'group/:slug', method: RequestMethod.DELETE }, - { path: 'group/user', method: RequestMethod.PUT }, - { path: '/group/user/delete', method: RequestMethod.PUT }, - { path: 'group/permission', method: RequestMethod.PUT }, - { path: '/group/permission/delete', method: RequestMethod.PUT }, - { path: 'group/delete/:groupId', method: RequestMethod.DELETE }, - { path: 'group/users/:groupId', method: RequestMethod.GET }, - { path: 'group/title', method: RequestMethod.PUT }, - ); - } + public configure(consumer: MiddlewareConsumer): any { + consumer + .apply(AuthMiddleware) + .forRoutes( + { path: 'groups', method: RequestMethod.GET }, + { path: 'group', method: RequestMethod.POST }, + { path: 'group/:slug', method: RequestMethod.DELETE }, + { path: 'group/user', method: RequestMethod.PUT }, + { path: '/group/user/delete', method: RequestMethod.PUT }, + { path: 'group/permission', method: RequestMethod.PUT }, + { path: '/group/permission/delete', method: RequestMethod.PUT }, + { path: 'group/delete/:groupId', method: RequestMethod.DELETE }, + { path: 'group/users/:groupId', method: RequestMethod.GET }, + { path: 'group/title', method: RequestMethod.PUT }, + ); + } } diff --git a/backend/src/entities/group/repository/group-custom-repository-extension.ts b/backend/src/entities/group/repository/group-custom-repository-extension.ts index 798069af3..a40ccf09f 100644 --- a/backend/src/entities/group/repository/group-custom-repository-extension.ts +++ b/backend/src/entities/group/repository/group-custom-repository-extension.ts @@ -5,93 +5,93 @@ import { GroupEntity } from '../group.entity.js'; import { IGroupRepository } from './group.repository.interface.js'; export const groupCustomRepositoryExtension: IGroupRepository = { - async saveNewOrUpdatedGroup(groupData: GroupEntity): Promise { - return await this.save(groupData); - }, + async saveNewOrUpdatedGroup(groupData: GroupEntity): Promise { + return await this.save(groupData); + }, - async findAllGroupsInConnection(connectionId: string): Promise> { - const qb = this.createQueryBuilder('group') - .leftJoinAndSelect('group.connection', 'connection') - .andWhere('connection.id = :id', { id: connectionId }); - return await qb.getMany(); - }, + async findAllGroupsInConnection(connectionId: string): Promise> { + const qb = this.createQueryBuilder('group') + .leftJoinAndSelect('group.connection', 'connection') + .andWhere('connection.id = :id', { id: connectionId }); + return await qb.getMany(); + }, - async createdAdminGroupInConnection(connection: ConnectionEntity, user: UserEntity): Promise { - const newGroup = new GroupEntity(); - newGroup.connection = connection; - newGroup.users = [user]; - newGroup.isMain = true; - newGroup.title = 'Admin'; - return await this.save(newGroup); - }, + async createdAdminGroupInConnection(connection: ConnectionEntity, user: UserEntity): Promise { + const newGroup = new GroupEntity(); + newGroup.connection = connection; + newGroup.users = [user]; + newGroup.isMain = true; + newGroup.title = 'Admin'; + return await this.save(newGroup); + }, - async findGroupInConnection(groupId: string, connectionId: string): Promise { - const qb = this.createQueryBuilder('group') - .leftJoinAndSelect('group.connection', 'connection') - .andWhere('group.id = :groupId', { groupId: groupId }) - .andWhere('connection.id = :connectionId', { connectionId: connectionId }); - return await qb.getOne(); - }, + async findGroupInConnection(groupId: string, connectionId: string): Promise { + const qb = this.createQueryBuilder('group') + .leftJoinAndSelect('group.connection', 'connection') + .andWhere('group.id = :groupId', { groupId: groupId }) + .andWhere('connection.id = :connectionId', { connectionId: connectionId }); + return await qb.getOne(); + }, - async removeGroupEntity(group: GroupEntity): Promise { - return await this.remove(group); - }, + async removeGroupEntity(group: GroupEntity): Promise { + return await this.remove(group); + }, - async findAllUserGroupsInConnection(connectionId: string, cognitoUserName: string): Promise> { - const qb = this.createQueryBuilder('group') - .leftJoinAndSelect('group.connection', 'connection') - .leftJoinAndSelect('group.users', 'user') - .andWhere('connection.id = :connectionId', { connectionId: connectionId }) - .andWhere('user.id = :cognitoUserName', { cognitoUserName: cognitoUserName }); - return await qb.getMany(); - }, + async findAllUserGroupsInConnection(connectionId: string, cognitoUserName: string): Promise> { + const qb = this.createQueryBuilder('group') + .leftJoinAndSelect('group.connection', 'connection') + .leftJoinAndSelect('group.users', 'user') + .andWhere('connection.id = :connectionId', { connectionId: connectionId }) + .andWhere('user.id = :cognitoUserName', { cognitoUserName: cognitoUserName }); + return await qb.getMany(); + }, - async findGroupByIdWithConnectionAndUsers(groupId: string): Promise { - const qb = this.createQueryBuilder('group') - .leftJoinAndSelect('group.connection', 'connection') - .leftJoinAndSelect('group.users', 'user') - .andWhere('group.id = :groupId', { groupId: groupId }); - return await qb.getOne(); - }, + async findGroupByIdWithConnectionAndUsers(groupId: string): Promise { + const qb = this.createQueryBuilder('group') + .leftJoinAndSelect('group.connection', 'connection') + .leftJoinAndSelect('group.users', 'user') + .andWhere('group.id = :groupId', { groupId: groupId }); + return await qb.getOne(); + }, - async findAllUserGroups(userId: string): Promise> { - const qb = this.createQueryBuilder('group') - .leftJoinAndSelect('group.users', 'user') - .andWhere('user.id = :userId', { userId: userId }); - return await qb.getMany(); - }, + async findAllUserGroups(userId: string): Promise> { + const qb = this.createQueryBuilder('group') + .leftJoinAndSelect('group.users', 'user') + .andWhere('user.id = :userId', { userId: userId }); + return await qb.getMany(); + }, - async findAllUsersInGroup(groupId: string): Promise> { - const qb = this.manager - .getRepository(UserEntity) - .createQueryBuilder('user') - .leftJoinAndSelect('user.groups', 'group') - .andWhere('group.id = :id', { id: groupId }); - return await qb.getMany(); - }, + async findAllUsersInGroup(groupId: string): Promise> { + const qb = this.manager + .getRepository(UserEntity) + .createQueryBuilder('user') + .leftJoinAndSelect('user.groups', 'group') + .andWhere('group.id = :id', { id: groupId }); + return await qb.getMany(); + }, - async findGroupWithPermissionsById(groupId: string): Promise { - const qb = this.createQueryBuilder('group') - .leftJoinAndSelect('group.permissions', 'permission') - .andWhere('group.id = :id', { id: groupId }); - return await qb.getOne(); - }, + async findGroupWithPermissionsById(groupId: string): Promise { + const qb = this.createQueryBuilder('group') + .leftJoinAndSelect('group.permissions', 'permission') + .andWhere('group.id = :id', { id: groupId }); + return await qb.getOne(); + }, - async findAllUsersInGroupsWhereUserIsAdmin(userId: string, connectionId: string): Promise> { - const userQb = this.manager - .getRepository(UserEntity) - .createQueryBuilder('user') - .leftJoinAndSelect('user.groups', 'group') - .leftJoinAndSelect('group.connection', 'connection') - .leftJoinAndSelect('group.permissions', 'permission') - .andWhere('user.id = :userId', { userId: userId }) - .andWhere('connection.id = :connectionId', { connectionId: connectionId }) - .andWhere('permission.type = :permissionType', { - permissionType: PermissionTypeEnum.Group, - }) - .andWhere('permission.accessLevel = :permissionAccessLevel', { - permissionAccessLevel: AccessLevelEnum.edit, - }); - return await userQb.getMany(); - }, + async findAllUsersInGroupsWhereUserIsAdmin(userId: string, connectionId: string): Promise> { + const userQb = this.manager + .getRepository(UserEntity) + .createQueryBuilder('user') + .leftJoinAndSelect('user.groups', 'group') + .leftJoinAndSelect('group.connection', 'connection') + .leftJoinAndSelect('group.permissions', 'permission') + .andWhere('user.id = :userId', { userId: userId }) + .andWhere('connection.id = :connectionId', { connectionId: connectionId }) + .andWhere('permission.type = :permissionType', { + permissionType: PermissionTypeEnum.Group, + }) + .andWhere('permission.accessLevel = :permissionAccessLevel', { + permissionAccessLevel: AccessLevelEnum.edit, + }); + return await userQb.getMany(); + }, }; diff --git a/backend/src/entities/group/repository/group.repository.interface.ts b/backend/src/entities/group/repository/group.repository.interface.ts index d4e03c061..899334bc9 100644 --- a/backend/src/entities/group/repository/group.repository.interface.ts +++ b/backend/src/entities/group/repository/group.repository.interface.ts @@ -3,25 +3,25 @@ import { UserEntity } from '../../user/user.entity.js'; import { GroupEntity } from '../group.entity.js'; export interface IGroupRepository { - saveNewOrUpdatedGroup(groupData: GroupEntity): Promise; + saveNewOrUpdatedGroup(groupData: GroupEntity): Promise; - findAllGroupsInConnection(connectionId: string): Promise>; + findAllGroupsInConnection(connectionId: string): Promise>; - createdAdminGroupInConnection(connection: ConnectionEntity, user: UserEntity): Promise; + createdAdminGroupInConnection(connection: ConnectionEntity, user: UserEntity): Promise; - findGroupInConnection(groupId: string, connectionId: string): Promise; + findGroupInConnection(groupId: string, connectionId: string): Promise; - removeGroupEntity(group: GroupEntity): Promise; + removeGroupEntity(group: GroupEntity): Promise; - findAllUserGroupsInConnection(connectionId: string, cognitoUserName: string): Promise>; + findAllUserGroupsInConnection(connectionId: string, cognitoUserName: string): Promise>; - findGroupByIdWithConnectionAndUsers(groupId: string): Promise; + findGroupByIdWithConnectionAndUsers(groupId: string): Promise; - findAllUserGroups(userId: string): Promise>; + findAllUserGroups(userId: string): Promise>; - findAllUsersInGroup(groupId: string): Promise>; + findAllUsersInGroup(groupId: string): Promise>; - findGroupWithPermissionsById(groupId: string): Promise; + findGroupWithPermissionsById(groupId: string): Promise; - findAllUsersInGroupsWhereUserIsAdmin(userId: string, connectionId: string): Promise>; + findAllUsersInGroupsWhereUserIsAdmin(userId: string, connectionId: string): Promise>; } diff --git a/backend/src/entities/group/use-cases/delete-group.use.case.ts b/backend/src/entities/group/use-cases/delete-group.use.case.ts index a9894aa6b..54c943c4d 100644 --- a/backend/src/entities/group/use-cases/delete-group.use.case.ts +++ b/backend/src/entities/group/use-cases/delete-group.use.case.ts @@ -8,28 +8,28 @@ import { IDeleteGroup } from './use-cases.interfaces.js'; @Injectable({ scope: Scope.REQUEST }) export class DeleteGroupUseCase extends AbstractUseCase implements IDeleteGroup { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(groupId: string): Promise { - const groupToDelete = await this._dbContext.groupRepository.findGroupByIdWithConnectionAndUsers(groupId); - if (groupToDelete.isMain) { - throw new HttpException( - { - message: Messages.CANT_DELETE_ADMIN_GROUP, - }, - HttpStatus.BAD_REQUEST, - ); - } - const deletedGroup = await this._dbContext.groupRepository.removeGroupEntity(groupToDelete); - return { - id: deletedGroup.id, - title: deletedGroup.title, - isMain: deletedGroup.isMain, - }; - } + protected async implementation(groupId: string): Promise { + const groupToDelete = await this._dbContext.groupRepository.findGroupByIdWithConnectionAndUsers(groupId); + if (groupToDelete.isMain) { + throw new HttpException( + { + message: Messages.CANT_DELETE_ADMIN_GROUP, + }, + HttpStatus.BAD_REQUEST, + ); + } + const deletedGroup = await this._dbContext.groupRepository.removeGroupEntity(groupToDelete); + return { + id: deletedGroup.id, + title: deletedGroup.title, + isMain: deletedGroup.isMain, + }; + } } diff --git a/backend/src/entities/group/use-cases/find-all-user-groups.use.case.ts b/backend/src/entities/group/use-cases/find-all-user-groups.use.case.ts index f495ec188..d5a549521 100644 --- a/backend/src/entities/group/use-cases/find-all-user-groups.use.case.ts +++ b/backend/src/entities/group/use-cases/find-all-user-groups.use.case.ts @@ -9,44 +9,44 @@ import { IFindUserGroups } from './use-cases.interfaces.js'; @Injectable() export class FindAllUserGroupsUseCase extends AbstractUseCase implements IFindUserGroups { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(userId: string): Promise { - const foundUserGroups: Array = await this._dbContext.groupRepository.findAllUserGroups(userId); - const groupsWithAccessLevels: Array<{ - group: GroupEntity; - accessLevel: AccessLevelEnum; - }> = await Promise.all( - foundUserGroups.map(async (group: GroupEntity) => { - const accessLevel = await this._dbContext.userAccessRepository.getGroupAccessLevel(userId, group.id); - return { - group: group, - accessLevel: accessLevel, - }; - }), - ); + protected async implementation(userId: string): Promise { + const foundUserGroups: Array = await this._dbContext.groupRepository.findAllUserGroups(userId); + const groupsWithAccessLevels: Array<{ + group: GroupEntity; + accessLevel: AccessLevelEnum; + }> = await Promise.all( + foundUserGroups.map(async (group: GroupEntity) => { + const accessLevel = await this._dbContext.userAccessRepository.getGroupAccessLevel(userId, group.id); + return { + group: group, + accessLevel: accessLevel, + }; + }), + ); - return { - groups: groupsWithAccessLevels.map((g) => { - const { - accessLevel, - group: { id, isMain, title }, - } = g; - return { - group: { - id: id, - title: title, - isMain: isMain, - }, - accessLevel: accessLevel, - }; - }), - groupsCount: groupsWithAccessLevels.length, - }; - } + return { + groups: groupsWithAccessLevels.map((g) => { + const { + accessLevel, + group: { id, isMain, title }, + } = g; + return { + group: { + id: id, + title: title, + isMain: isMain, + }, + accessLevel: accessLevel, + }; + }), + groupsCount: groupsWithAccessLevels.length, + }; + } } diff --git a/backend/src/entities/group/use-cases/find-all-users-in-group.use.case.ts b/backend/src/entities/group/use-cases/find-all-users-in-group.use.case.ts index a55182c20..c85b4b05a 100644 --- a/backend/src/entities/group/use-cases/find-all-users-in-group.use.case.ts +++ b/backend/src/entities/group/use-cases/find-all-users-in-group.use.case.ts @@ -9,21 +9,21 @@ import { IFindAllUsersInGroup } from './use-cases.interfaces.js'; @Injectable() export class FindAllUsersInGroupUseCase - extends AbstractUseCase> - implements IFindAllUsersInGroup + extends AbstractUseCase> + implements IFindAllUsersInGroup { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private readonly userHelperService: UserHelperService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly userHelperService: UserHelperService, + ) { + super(); + } - protected async implementation(groupId: string): Promise> { - const result: Array = await this._dbContext.groupRepository.findAllUsersInGroup(groupId); - return result.map((user: UserEntity) => { - return this.userHelperService.buildFoundUserInGroupDs(user); - }); - } + protected async implementation(groupId: string): Promise> { + const result: Array = await this._dbContext.groupRepository.findAllUsersInGroup(groupId); + return result.map((user: UserEntity) => { + return this.userHelperService.buildFoundUserInGroupDs(user); + }); + } } diff --git a/backend/src/entities/group/use-cases/remove-user-from-group.use.case.ts b/backend/src/entities/group/use-cases/remove-user-from-group.use.case.ts index 98fa56c75..c9fb1f094 100644 --- a/backend/src/entities/group/use-cases/remove-user-from-group.use.case.ts +++ b/backend/src/entities/group/use-cases/remove-user-from-group.use.case.ts @@ -10,51 +10,49 @@ import { IRemoveUserFromGroup } from './use-cases.interfaces.js'; @Injectable({ scope: Scope.REQUEST }) export class RemoveUserFromGroupUseCase - extends AbstractUseCase - implements IRemoveUserFromGroup + extends AbstractUseCase + implements IRemoveUserFromGroup { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: AddUserInGroupDs): Promise { - const { groupId } = inputData; - const email = inputData.email.toLowerCase(); - const foundUser = await this._dbContext.userRepository.findOneUserByEmailAndGroupId(email, groupId); - if (!foundUser) { - throw new HttpException( - { - message: Messages.USER_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - const groupToUpdate = await this._dbContext.groupRepository.findGroupByIdWithConnectionAndUsers(groupId); - if (groupToUpdate.isMain && groupToUpdate.users.length <= 1) { - throw new HttpException( - { - message: Messages.CANT_DELETE_LAST_USER, - }, - HttpStatus.FORBIDDEN, - ); - } - const usersArray = groupToUpdate.users; - const delIndex = usersArray - .map((e) => e.id) - .indexOf(foundUser.id); - if (delIndex === -1) { - throw new HttpException( - { - message: Messages.USER_NOT_FOUND, - }, - HttpStatus.NOT_FOUND, - ); - } - groupToUpdate.users.splice(delIndex, 1); - const updatedGroup = await this._dbContext.groupRepository.saveNewOrUpdatedGroup(groupToUpdate); - return buildRemoveUserFromGroupResultDs(updatedGroup); - } + protected async implementation(inputData: AddUserInGroupDs): Promise { + const { groupId } = inputData; + const email = inputData.email.toLowerCase(); + const foundUser = await this._dbContext.userRepository.findOneUserByEmailAndGroupId(email, groupId); + if (!foundUser) { + throw new HttpException( + { + message: Messages.USER_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + const groupToUpdate = await this._dbContext.groupRepository.findGroupByIdWithConnectionAndUsers(groupId); + if (groupToUpdate.isMain && groupToUpdate.users.length <= 1) { + throw new HttpException( + { + message: Messages.CANT_DELETE_LAST_USER, + }, + HttpStatus.FORBIDDEN, + ); + } + const usersArray = groupToUpdate.users; + const delIndex = usersArray.map((e) => e.id).indexOf(foundUser.id); + if (delIndex === -1) { + throw new HttpException( + { + message: Messages.USER_NOT_FOUND, + }, + HttpStatus.NOT_FOUND, + ); + } + groupToUpdate.users.splice(delIndex, 1); + const updatedGroup = await this._dbContext.groupRepository.saveNewOrUpdatedGroup(groupToUpdate); + return buildRemoveUserFromGroupResultDs(updatedGroup); + } } diff --git a/backend/src/entities/group/use-cases/saas-add-user-in-group-v2.use.case.ts b/backend/src/entities/group/use-cases/saas-add-user-in-group-v2.use.case.ts index 16d7baea5..df4521138 100644 --- a/backend/src/entities/group/use-cases/saas-add-user-in-group-v2.use.case.ts +++ b/backend/src/entities/group/use-cases/saas-add-user-in-group-v2.use.case.ts @@ -10,83 +10,83 @@ import { buildFoundGroupResponseDto } from '../utils/biuld-found-group-response. import { IAddUserInGroup } from './use-cases.interfaces.js'; export class AddUserInGroupUseCase - extends AbstractUseCase - implements IAddUserInGroup + extends AbstractUseCase + implements IAddUserInGroup { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private readonly emailService: EmailService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly emailService: EmailService, + ) { + super(); + } - protected async implementation(inputData: AddUserInGroupWithSaaSDs): Promise { - const { groupId } = inputData; - const email = inputData.email.toLowerCase(); - const foundGroup = await this._dbContext.groupRepository.findGroupByIdWithConnectionAndUsers(groupId); + protected async implementation(inputData: AddUserInGroupWithSaaSDs): Promise { + const { groupId } = inputData; + const email = inputData.email.toLowerCase(); + const foundGroup = await this._dbContext.groupRepository.findGroupByIdWithConnectionAndUsers(groupId); - const foundConnection = - await this._dbContext.connectionRepository.getConnectionByGroupIdWithCompanyAndUsersInCompany(groupId); + const foundConnection = + await this._dbContext.connectionRepository.getConnectionByGroupIdWithCompanyAndUsersInCompany(groupId); - if (!foundConnection) { - throw new HttpException( - { - message: Messages.CONNECTION_NOT_FOUND, - }, - HttpStatus.NOT_FOUND, - ); - } + if (!foundConnection) { + throw new HttpException( + { + message: Messages.CONNECTION_NOT_FOUND, + }, + HttpStatus.NOT_FOUND, + ); + } - if (!foundConnection.company || !foundConnection.company.id) { - throw new HttpException( - { - message: Messages.COMPANY_NOT_EXISTS_IN_CONNECTION, - }, - HttpStatus.INTERNAL_SERVER_ERROR, - ); - } + if (!foundConnection.company || !foundConnection.company.id) { + throw new HttpException( + { + message: Messages.COMPANY_NOT_EXISTS_IN_CONNECTION, + }, + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } - const companyWithUsers = await this._dbContext.companyInfoRepository.findCompanyInfoWithUsersById( - foundConnection.company.id, - ); + const companyWithUsers = await this._dbContext.companyInfoRepository.findCompanyInfoWithUsersById( + foundConnection.company.id, + ); - if (!companyWithUsers) { - throw new HttpException( - { - message: Messages.COMPANY_NOT_EXISTS_IN_CONNECTION, - }, - HttpStatus.INTERNAL_SERVER_ERROR, - ); - } + if (!companyWithUsers) { + throw new HttpException( + { + message: Messages.COMPANY_NOT_EXISTS_IN_CONNECTION, + }, + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } - const foundUser = companyWithUsers.users.find((u) => u.email.toLowerCase() === email); - if (!foundUser) { - throw new HttpException( - { - message: Messages.USER_NOT_INVITED_IN_COMPANY(email), - }, - HttpStatus.BAD_REQUEST, - ); - } + const foundUser = companyWithUsers.users.find((u) => u.email.toLowerCase() === email); + if (!foundUser) { + throw new HttpException( + { + message: Messages.USER_NOT_INVITED_IN_COMPANY(email), + }, + HttpStatus.BAD_REQUEST, + ); + } - const userAlreadyAdded = !!foundGroup.users.find((u) => u.id === foundUser.id); - if (userAlreadyAdded) { - throw new HttpException( - { - message: Messages.USER_ALREADY_ADDED, - }, - HttpStatus.BAD_REQUEST, - ); - } + const userAlreadyAdded = !!foundGroup.users.find((u) => u.id === foundUser.id); + if (userAlreadyAdded) { + throw new HttpException( + { + message: Messages.USER_ALREADY_ADDED, + }, + HttpStatus.BAD_REQUEST, + ); + } - foundGroup.users.push(foundUser); - const savedGroup = await this._dbContext.groupRepository.saveNewOrUpdatedGroup(foundGroup); - await this.emailService.sendInvitedInNewGroup(foundUser.email.toLowerCase(), foundGroup.title); - return { - group: buildFoundGroupResponseDto(savedGroup), - message: Messages.USER_ADDED_IN_GROUP(foundUser.email.toLowerCase()), - external_invite: false, - }; - } + foundGroup.users.push(foundUser); + const savedGroup = await this._dbContext.groupRepository.saveNewOrUpdatedGroup(foundGroup); + await this.emailService.sendInvitedInNewGroup(foundUser.email.toLowerCase(), foundGroup.title); + return { + group: buildFoundGroupResponseDto(savedGroup), + message: Messages.USER_ADDED_IN_GROUP(foundUser.email.toLowerCase()), + external_invite: false, + }; + } } diff --git a/backend/src/entities/group/use-cases/update-group-title.use.case.ts b/backend/src/entities/group/use-cases/update-group-title.use.case.ts index 917e0ae55..d36918baf 100644 --- a/backend/src/entities/group/use-cases/update-group-title.use.case.ts +++ b/backend/src/entities/group/use-cases/update-group-title.use.case.ts @@ -2,48 +2,48 @@ import { BadRequestException, HttpException, HttpStatus, Inject, Injectable, Sco import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; +import { Messages } from '../../../exceptions/text/messages.js'; import { FoundGroupDataInfoDs } from '../application/data-sctructures/found-user-groups.ds.js'; import { UpdateGroupTitleDto } from '../dto/update-group-title.dto.js'; import { IUpdateGroupTitle } from './use-cases.interfaces.js'; -import { Messages } from '../../../exceptions/text/messages.js'; @Injectable({ scope: Scope.REQUEST }) export class UpdateGroupTitleUseCase - extends AbstractUseCase - implements IUpdateGroupTitle + extends AbstractUseCase + implements IUpdateGroupTitle { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(groupData: UpdateGroupTitleDto): Promise { - const { groupId, title } = groupData; - const groupToUpdate = await this._dbContext.groupRepository.findGroupByIdWithConnectionAndUsers(groupId); - if (!groupToUpdate) { - throw new HttpException( - { - message: Messages.GROUP_NOT_FOUND, - }, - HttpStatus.NOT_FOUND, - ); - } - const connectionWithGroups = await this._dbContext.connectionRepository.findConnectionWithGroups( - groupToUpdate.connection.id, - ); + protected async implementation(groupData: UpdateGroupTitleDto): Promise { + const { groupId, title } = groupData; + const groupToUpdate = await this._dbContext.groupRepository.findGroupByIdWithConnectionAndUsers(groupId); + if (!groupToUpdate) { + throw new HttpException( + { + message: Messages.GROUP_NOT_FOUND, + }, + HttpStatus.NOT_FOUND, + ); + } + const connectionWithGroups = await this._dbContext.connectionRepository.findConnectionWithGroups( + groupToUpdate.connection.id, + ); - if (connectionWithGroups.groups.find((group) => group.title === title)) { - throw new BadRequestException(Messages.GROUP_NAME_UNIQUE); - } + if (connectionWithGroups.groups.find((group) => group.title === title)) { + throw new BadRequestException(Messages.GROUP_NAME_UNIQUE); + } - groupToUpdate.title = title; - const updatedGroup = await this._dbContext.groupRepository.saveNewOrUpdatedGroup(groupToUpdate); - return { - id: updatedGroup.id, - title: updatedGroup.title, - isMain: updatedGroup.isMain, - }; - } + groupToUpdate.title = title; + const updatedGroup = await this._dbContext.groupRepository.saveNewOrUpdatedGroup(groupToUpdate); + return { + id: updatedGroup.id, + title: updatedGroup.title, + isMain: updatedGroup.isMain, + }; + } } diff --git a/backend/src/entities/group/use-cases/use-cases.interfaces.ts b/backend/src/entities/group/use-cases/use-cases.interfaces.ts index 0b9e9dc65..5f0974773 100644 --- a/backend/src/entities/group/use-cases/use-cases.interfaces.ts +++ b/backend/src/entities/group/use-cases/use-cases.interfaces.ts @@ -8,25 +8,25 @@ import { RemoveUserFromGroupResultDs } from '../application/data-sctructures/rem import { UpdateGroupTitleDto } from '../dto/update-group-title.dto.js'; export interface IAddUserInGroup { - execute(inputData: AddUserInGroupWithSaaSDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: AddUserInGroupWithSaaSDs, inTransaction: InTransactionEnum): Promise; } export interface IFindUserGroups { - execute(inputData: string, inTransaction: InTransactionEnum): Promise; + execute(inputData: string, inTransaction: InTransactionEnum): Promise; } export interface IFindAllUsersInGroup { - execute(inputData: string, inTransaction: InTransactionEnum): Promise>; + execute(inputData: string, inTransaction: InTransactionEnum): Promise>; } export interface IRemoveUserFromGroup { - execute(inputData: AddUserInGroupDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: AddUserInGroupDs, inTransaction: InTransactionEnum): Promise; } export interface IDeleteGroup { - execute(groupId: string, inTransaction: InTransactionEnum): Promise; + execute(groupId: string, inTransaction: InTransactionEnum): Promise; } export interface IUpdateGroupTitle { - execute(inputData: UpdateGroupTitleDto, inTransaction: InTransactionEnum): Promise; + execute(inputData: UpdateGroupTitleDto, inTransaction: InTransactionEnum): Promise; } diff --git a/backend/src/entities/group/utils/biuld-found-group-response.dto.ts b/backend/src/entities/group/utils/biuld-found-group-response.dto.ts index 186a72514..63804fef3 100644 --- a/backend/src/entities/group/utils/biuld-found-group-response.dto.ts +++ b/backend/src/entities/group/utils/biuld-found-group-response.dto.ts @@ -3,10 +3,10 @@ import { FoundGroupResponseDto } from '../dto/found-group-response.dto.js'; import { GroupEntity } from '../group.entity.js'; export function buildFoundGroupResponseDto(group: GroupEntity): FoundGroupResponseDto { - return { - id: group.id, - title: group.title, - isMain: group.isMain, - users: group.users?.map((user) => buildSimpleUserInfoDs(user)), - }; + return { + id: group.id, + title: group.title, + isMain: group.isMain, + users: group.users?.map((user) => buildSimpleUserInfoDs(user)), + }; } diff --git a/backend/src/entities/group/utils/build-remove-user-from-group-result.ds.ts b/backend/src/entities/group/utils/build-remove-user-from-group-result.ds.ts index 5229da541..104fb76a2 100644 --- a/backend/src/entities/group/utils/build-remove-user-from-group-result.ds.ts +++ b/backend/src/entities/group/utils/build-remove-user-from-group-result.ds.ts @@ -1,19 +1,19 @@ -import { GroupEntity } from '../group.entity.js'; -import { RemoveUserFromGroupResultDs } from '../application/data-sctructures/remove-user-from-group-result.ds.js'; import { UserEntity } from '../../user/user.entity.js'; +import { RemoveUserFromGroupResultDs } from '../application/data-sctructures/remove-user-from-group-result.ds.js'; +import { GroupEntity } from '../group.entity.js'; export function buildRemoveUserFromGroupResultDs(group: GroupEntity): RemoveUserFromGroupResultDs { - return { - id: group.id, - isMain: group.isMain, - title: group.title, - users: group.users.map((u: UserEntity) => { - return { - id: u.id, - email: u.email, - createdAt: u.createdAt, - isActive: u.isActive, - }; - }), - }; + return { + id: group.id, + isMain: group.isMain, + title: group.title, + users: group.users.map((u: UserEntity) => { + return { + id: u.id, + email: u.email, + createdAt: u.createdAt, + isActive: u.isActive, + }; + }), + }; } diff --git a/backend/src/entities/log-out/log-out.entity.ts b/backend/src/entities/log-out/log-out.entity.ts index 0020e5211..3300e00f2 100644 --- a/backend/src/entities/log-out/log-out.entity.ts +++ b/backend/src/entities/log-out/log-out.entity.ts @@ -2,12 +2,12 @@ import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; @Entity('logout') export class LogOutEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ default: null }) - jwtToken: string; + @Column({ default: null }) + jwtToken: string; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - createdAt: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + createdAt: Date; } diff --git a/backend/src/entities/log-out/repository/log-out-custom-repository-extension.ts b/backend/src/entities/log-out/repository/log-out-custom-repository-extension.ts index c4246b5ee..a8d7e6f8a 100644 --- a/backend/src/entities/log-out/repository/log-out-custom-repository-extension.ts +++ b/backend/src/entities/log-out/repository/log-out-custom-repository-extension.ts @@ -2,25 +2,25 @@ import { Constants } from '../../../helpers/constants/constants.js'; import { LogOutEntity } from '../log-out.entity.js'; export const logOutCustomRepositoryExtension = { - async saveLogOutUserToken(token: string): Promise { - const newLogOut = new LogOutEntity(); - newLogOut.jwtToken = token; - await this.save(newLogOut); - }, + async saveLogOutUserToken(token: string): Promise { + const newLogOut = new LogOutEntity(); + newLogOut.jwtToken = token; + await this.save(newLogOut); + }, - async isLoggedOut(token: string): Promise { - const logOutQb = this.createQueryBuilder('logout').where('logout.jwtToken = :token', { token: token }); - return !!(await logOutQb.getOne()); - }, + async isLoggedOut(token: string): Promise { + const logOutQb = this.createQueryBuilder('logout').where('logout.jwtToken = :token', { token: token }); + return !!(await logOutQb.getOne()); + }, - async cleanOldTokens(): Promise { - const logOutQb = this.createQueryBuilder('logout').andWhere('logout.createdAt <= :date', { - date: Constants.ONE_DAY_AGO(), - }); - const entitiesForRemoving = await logOutQb.getMany(); - if (entitiesForRemoving.length === 0) { - return; - } - await this.remove(entitiesForRemoving); - }, + async cleanOldTokens(): Promise { + const logOutQb = this.createQueryBuilder('logout').andWhere('logout.createdAt <= :date', { + date: Constants.ONE_DAY_AGO(), + }); + const entitiesForRemoving = await logOutQb.getMany(); + if (entitiesForRemoving.length === 0) { + return; + } + await this.remove(entitiesForRemoving); + }, }; diff --git a/backend/src/entities/log-out/repository/log-out-repository.interface.ts b/backend/src/entities/log-out/repository/log-out-repository.interface.ts index 2415bbf13..a2f0cf8b1 100644 --- a/backend/src/entities/log-out/repository/log-out-repository.interface.ts +++ b/backend/src/entities/log-out/repository/log-out-repository.interface.ts @@ -1,7 +1,7 @@ export interface ILogOutRepository { - saveLogOutUserToken(token: string): Promise; + saveLogOutUserToken(token: string): Promise; - isLoggedOut(token: string): Promise; + isLoggedOut(token: string): Promise; - cleanOldTokens(): Promise; + cleanOldTokens(): Promise; } diff --git a/backend/src/entities/logging/logger-transports.config.ts b/backend/src/entities/logging/logger-transports.config.ts index cf2f9c806..e72f81782 100644 --- a/backend/src/entities/logging/logger-transports.config.ts +++ b/backend/src/entities/logging/logger-transports.config.ts @@ -1,30 +1,30 @@ import winston from 'winston'; export const LoggerTransports = { - default: [ - new winston.transports.Console({ - format: winston.format.combine( - winston.format.timestamp(), - winston.format.errors({ stack: true }), - winston.format.json(), - ), - }), - ], - debug: [ - new winston.transports.Console({ - format: winston.format.combine( - winston.format.timestamp(), - winston.format.errors({ stack: true }), - winston.format.colorize({ - all: true, - colors: { info: 'blue', error: 'red', warn: 'yellow', debug: 'cyan' }, - }), - winston.format.printf(({ timestamp, level, message, context, trace }) => { - const logContext = context ? ` [${context}]` : ''; - const logTrace = trace ? `\nTrace: ${trace}` : ''; - return `${timestamp} [${level}]${logContext}: ${message}${logTrace}`; - }), - ), - }), - ], + default: [ + new winston.transports.Console({ + format: winston.format.combine( + winston.format.timestamp(), + winston.format.errors({ stack: true }), + winston.format.json(), + ), + }), + ], + debug: [ + new winston.transports.Console({ + format: winston.format.combine( + winston.format.timestamp(), + winston.format.errors({ stack: true }), + winston.format.colorize({ + all: true, + colors: { info: 'blue', error: 'red', warn: 'yellow', debug: 'cyan' }, + }), + winston.format.printf(({ timestamp, level, message, context, trace }) => { + const logContext = context ? ` [${context}]` : ''; + const logTrace = trace ? `\nTrace: ${trace}` : ''; + return `${timestamp} [${level}]${logContext}: ${message}${logTrace}`; + }), + ), + }), + ], }; diff --git a/backend/src/entities/logging/logging.module.ts b/backend/src/entities/logging/logging.module.ts index d294bccf9..903c1b086 100644 --- a/backend/src/entities/logging/logging.module.ts +++ b/backend/src/entities/logging/logging.module.ts @@ -3,7 +3,7 @@ import { WinstonLogger } from './winston-logger.js'; @Global() @Module({ - providers: [WinstonLogger], - exports: [WinstonLogger], + providers: [WinstonLogger], + exports: [WinstonLogger], }) export class LoggingModule {} diff --git a/backend/src/entities/logging/winston-logger.ts b/backend/src/entities/logging/winston-logger.ts index 4c3c914b4..e1eae90c8 100644 --- a/backend/src/entities/logging/winston-logger.ts +++ b/backend/src/entities/logging/winston-logger.ts @@ -5,54 +5,54 @@ import { LoggerTransports } from './logger-transports.config.js'; @Injectable() export class WinstonLogger implements LoggerService { - private readonly logger: winston.Logger; - - constructor() { - this.logger = winston.createLogger({ - level: process.env.LOG_LEVEL || 'info', - transports: LoggerTransports.default, - }); - } - - public log(message: any, ...optionalParams: any[]) { - this.logger.info(message, ...optionalParams); - } - - public info(message: any, ...optionalParams: any[]) { - this.logger.info(message, ...optionalParams); - } - - public error(message: any, ...optionalParams: any[]) { - this.logger.error(message, ...optionalParams); - } - - public warn(message: any, ...optionalParams: any[]) { - this.logger.warn(message, ...optionalParams); - } - - public logWithSlack(message: any, ...optionalParams: any[]) { - this.logger.error(message, ...optionalParams); - slackPostMessage(message).catch((error) => { - this.logger.error('Failed to send Slack message', error); - }); - } - - public printTechString(str: string): void { - this.logger.info(`\n ${str} \n`); - } - - public debug(message: any, ...optionalParams: any[]) { - this.logger.debug(message, ...optionalParams); - } - - public verbose(message: any, ...optionalParams: any[]) { - this.logger.verbose(message, ...optionalParams); - } - - public fatal(message: any, ...optionalParams: any[]) { - this.logger.error(message, ...optionalParams); - slackPostMessage(message).catch((error) => { - this.logger.error('Failed to send Slack message', error); - }); - } + private readonly logger: winston.Logger; + + constructor() { + this.logger = winston.createLogger({ + level: process.env.LOG_LEVEL || 'info', + transports: LoggerTransports.default, + }); + } + + public log(message: any, ...optionalParams: any[]) { + this.logger.info(message, ...optionalParams); + } + + public info(message: any, ...optionalParams: any[]) { + this.logger.info(message, ...optionalParams); + } + + public error(message: any, ...optionalParams: any[]) { + this.logger.error(message, ...optionalParams); + } + + public warn(message: any, ...optionalParams: any[]) { + this.logger.warn(message, ...optionalParams); + } + + public logWithSlack(message: any, ...optionalParams: any[]) { + this.logger.error(message, ...optionalParams); + slackPostMessage(message).catch((error) => { + this.logger.error('Failed to send Slack message', error); + }); + } + + public printTechString(str: string): void { + this.logger.info(`\n ${str} \n`); + } + + public debug(message: any, ...optionalParams: any[]) { + this.logger.debug(message, ...optionalParams); + } + + public verbose(message: any, ...optionalParams: any[]) { + this.logger.verbose(message, ...optionalParams); + } + + public fatal(message: any, ...optionalParams: any[]) { + this.logger.error(message, ...optionalParams); + slackPostMessage(message).catch((error) => { + this.logger.error('Failed to send Slack message', error); + }); + } } diff --git a/backend/src/entities/permission/application/data-structures/create-permissions.ds.ts b/backend/src/entities/permission/application/data-structures/create-permissions.ds.ts index cbccc3977..3e2046a0a 100644 --- a/backend/src/entities/permission/application/data-structures/create-permissions.ds.ts +++ b/backend/src/entities/permission/application/data-structures/create-permissions.ds.ts @@ -1,90 +1,90 @@ import { ApiProperty } from '@nestjs/swagger'; -import { AccessLevelEnum } from '../../../../enums/index.js'; import { IsArray, IsBoolean, IsEnum, IsString, IsUUID, ValidateNested } from 'class-validator'; +import { AccessLevelEnum } from '../../../../enums/index.js'; export class CreatePermissionsDs { - groupId: string; - masterPwd: string; - permissions: PermissionsDs; - userId: string; + groupId: string; + masterPwd: string; + permissions: PermissionsDs; + userId: string; } export class PermissionsDs { - connection: { - accessLevel: AccessLevelEnum; - connectionId: string; - }; - group: { - accessLevel: AccessLevelEnum; - groupId: string; - }; - tables: Array; + connection: { + accessLevel: AccessLevelEnum; + connectionId: string; + }; + group: { + accessLevel: AccessLevelEnum; + groupId: string; + }; + tables: Array; } export class TableAccessLevelsDs { - @ApiProperty() - @IsBoolean() - add: boolean; + @ApiProperty() + @IsBoolean() + add: boolean; - @ApiProperty() - @IsBoolean() - delete: boolean; + @ApiProperty() + @IsBoolean() + delete: boolean; - @ApiProperty() - @IsBoolean() - edit: boolean; + @ApiProperty() + @IsBoolean() + edit: boolean; - @ApiProperty() - @IsBoolean() - readonly: boolean; + @ApiProperty() + @IsBoolean() + readonly: boolean; - @ApiProperty() - @IsBoolean() - visibility: boolean; + @ApiProperty() + @IsBoolean() + visibility: boolean; } export class TablePermissionDs { - @ApiProperty({ type: TableAccessLevelsDs }) - @ValidateNested() - accessLevel: TableAccessLevelsDs; + @ApiProperty({ type: TableAccessLevelsDs }) + @ValidateNested() + accessLevel: TableAccessLevelsDs; - @ApiProperty() - @IsString() - tableName: string; + @ApiProperty() + @IsString() + tableName: string; } export class GroupPermissionDs { - @ApiProperty() - @IsString() - @IsUUID() - groupId: string; - - @ApiProperty({ enum: AccessLevelEnum }) - @IsEnum(AccessLevelEnum) - accessLevel: AccessLevelEnum; + @ApiProperty() + @IsString() + @IsUUID() + groupId: string; + + @ApiProperty({ enum: AccessLevelEnum }) + @IsEnum(AccessLevelEnum) + accessLevel: AccessLevelEnum; } export class ConnectionPermissionDs { - @ApiProperty() - @IsString() - connectionId: string; + @ApiProperty() + @IsString() + connectionId: string; - @ApiProperty({ enum: AccessLevelEnum }) - @IsEnum(AccessLevelEnum) - accessLevel: AccessLevelEnum; + @ApiProperty({ enum: AccessLevelEnum }) + @IsEnum(AccessLevelEnum) + accessLevel: AccessLevelEnum; } export class ComplexPermissionDs { - @ApiProperty({ type: ConnectionPermissionDs }) - @ValidateNested() - connection: ConnectionPermissionDs; - - @ApiProperty({ type: GroupPermissionDs }) - @ValidateNested() - group: GroupPermissionDs; - - @ApiProperty({ isArray: true, type: TablePermissionDs }) - @IsArray() - @ValidateNested({ each: true }) - tables: Array; + @ApiProperty({ type: ConnectionPermissionDs }) + @ValidateNested() + connection: ConnectionPermissionDs; + + @ApiProperty({ type: GroupPermissionDs }) + @ValidateNested() + group: GroupPermissionDs; + + @ApiProperty({ isArray: true, type: TablePermissionDs }) + @IsArray() + @ValidateNested({ each: true }) + tables: Array; } diff --git a/backend/src/entities/permission/permission.controller.ts b/backend/src/entities/permission/permission.controller.ts index 4863b5647..8fa285f97 100644 --- a/backend/src/entities/permission/permission.controller.ts +++ b/backend/src/entities/permission/permission.controller.ts @@ -12,13 +12,13 @@ import { import { ApiBearerAuth, ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import { UseCaseType } from '../../common/data-injection.tokens.js'; import { MasterPassword, SlugUuid, UserId } from '../../decorators/index.js'; +import { Timeout } from '../../decorators/timeout.decorator.js'; import { InTransactionEnum } from '../../enums/index.js'; import { Messages } from '../../exceptions/text/messages.js'; import { ConnectionEditGuard } from '../../guards/index.js'; import { SentryInterceptor } from '../../interceptors/index.js'; import { ComplexPermissionDs, CreatePermissionsDs } from './application/data-structures/create-permissions.ds.js'; import { ICreateOrUpdatePermissions } from './use-cases/permissions-use-cases.interface.js'; -import { Timeout } from '../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/permission/permission.entity.ts b/backend/src/entities/permission/permission.entity.ts index 808485348..da99651c2 100644 --- a/backend/src/entities/permission/permission.entity.ts +++ b/backend/src/entities/permission/permission.entity.ts @@ -1,21 +1,24 @@ -import { Entity, PrimaryGeneratedColumn, Column, ManyToMany, JoinTable, Relation } from 'typeorm'; +import { Column, Entity, JoinTable, ManyToMany, PrimaryGeneratedColumn, Relation } from 'typeorm'; import { GroupEntity } from '../group/group.entity.js'; @Entity('permission') export class PermissionEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column() - type: string; + @Column() + type: string; - @Column() - accessLevel: string; + @Column() + accessLevel: string; - @Column({ default: '' }) - tableName?: string; //todo need reworking to required + @Column({ default: '' }) + tableName?: string; //todo need reworking to required - @ManyToMany(() => GroupEntity, (group) => group.permissions) - @JoinTable() - groups: Relation[]; + @ManyToMany( + () => GroupEntity, + (group) => group.permissions, + ) + @JoinTable() + groups: Relation[]; } diff --git a/backend/src/entities/permission/permission.interface.ts b/backend/src/entities/permission/permission.interface.ts index fc8a1c3fa..bcc792ef7 100644 --- a/backend/src/entities/permission/permission.interface.ts +++ b/backend/src/entities/permission/permission.interface.ts @@ -1,34 +1,34 @@ import { AccessLevelEnum } from '../../enums/index.js'; export interface IComplexPermission { - connection: IConnectionPermissionData; - group: IGroupPermissionData; - tables: Array; + connection: IConnectionPermissionData; + group: IGroupPermissionData; + tables: Array; } export interface IConnectionPermissionData { - connectionId: string; - accessLevel: AccessLevelEnum; + connectionId: string; + accessLevel: AccessLevelEnum; } export interface IGroupPermissionData { - groupId: string; - accessLevel: AccessLevelEnum; + groupId: string; + accessLevel: AccessLevelEnum; } export interface ITableAccessLevel { - visibility: boolean; - readonly: boolean; - add: boolean; - delete: boolean; - edit: boolean; + visibility: boolean; + readonly: boolean; + add: boolean; + delete: boolean; + edit: boolean; } export interface ITablePermissionData { - tableName: string; - accessLevel: ITableAccessLevel; + tableName: string; + accessLevel: ITableAccessLevel; } export interface ITableAndViewPermissionData extends ITablePermissionData { - isView: boolean; + isView: boolean; } diff --git a/backend/src/entities/permission/permission.module.ts b/backend/src/entities/permission/permission.module.ts index 2e62f24bd..f4cf4e254 100644 --- a/backend/src/entities/permission/permission.module.ts +++ b/backend/src/entities/permission/permission.module.ts @@ -4,8 +4,8 @@ import { AuthMiddleware } from '../../authorization/index.js'; import { GlobalDatabaseContext } from '../../common/application/global-database-context.js'; import { BaseType, UseCaseType } from '../../common/data-injection.tokens.js'; import { AgentModule } from '../agent/agent.module.js'; -import { ConnectionPropertiesEntity } from '../connection-properties/connection-properties.entity.js'; import { ConnectionEntity } from '../connection/connection.entity.js'; +import { ConnectionPropertiesEntity } from '../connection-properties/connection-properties.entity.js'; import { CustomFieldsEntity } from '../custom-field/custom-fields.entity.js'; import { GroupEntity } from '../group/group.entity.js'; import { GroupModule } from '../group/group.module.js'; @@ -19,46 +19,46 @@ import { PermissionEntity } from './permission.entity.js'; import { CreateOrUpdatePermissionsUseCase } from './use-cases/create-or-update-permissions.use.case.js'; @Module({ - imports: [ - TypeOrmModule.forFeature([ - ConnectionEntity, - CustomFieldsEntity, - GroupEntity, - PermissionEntity, - TableLogsEntity, - TableSettingsEntity, - TableWidgetEntity, - UserEntity, - ConnectionPropertiesEntity, - LogOutEntity, - ]), - AgentModule, - GroupModule, - ], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.CREATE_OR_UPDATE_PERMISSIONS, - useClass: CreateOrUpdatePermissionsUseCase, - }, - ], - controllers: [PermissionController], - exports: [], + imports: [ + TypeOrmModule.forFeature([ + ConnectionEntity, + CustomFieldsEntity, + GroupEntity, + PermissionEntity, + TableLogsEntity, + TableSettingsEntity, + TableWidgetEntity, + UserEntity, + ConnectionPropertiesEntity, + LogOutEntity, + ]), + AgentModule, + GroupModule, + ], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.CREATE_OR_UPDATE_PERMISSIONS, + useClass: CreateOrUpdatePermissionsUseCase, + }, + ], + controllers: [PermissionController], + exports: [], }) export class PermissionModule implements NestModule { - public configure(consumer: MiddlewareConsumer): any { - consumer - .apply(AuthMiddleware) - .forRoutes( - { path: 'permissions/all', method: RequestMethod.GET }, - { path: 'permission/:slug', method: RequestMethod.POST }, - { path: 'permission/group/:slug', method: RequestMethod.POST }, - { path: 'permission/group/:slug', method: RequestMethod.PUT }, - { path: 'permissions/:slug', method: RequestMethod.POST }, - { path: 'permissions/:slug', method: RequestMethod.PUT }, - ); - } + public configure(consumer: MiddlewareConsumer): any { + consumer + .apply(AuthMiddleware) + .forRoutes( + { path: 'permissions/all', method: RequestMethod.GET }, + { path: 'permission/:slug', method: RequestMethod.POST }, + { path: 'permission/group/:slug', method: RequestMethod.POST }, + { path: 'permission/group/:slug', method: RequestMethod.PUT }, + { path: 'permissions/:slug', method: RequestMethod.POST }, + { path: 'permissions/:slug', method: RequestMethod.PUT }, + ); + } } diff --git a/backend/src/entities/permission/repository/permission-custom-repository-extension.ts b/backend/src/entities/permission/repository/permission-custom-repository-extension.ts index 46ed8c875..f663aa429 100644 --- a/backend/src/entities/permission/repository/permission-custom-repository-extension.ts +++ b/backend/src/entities/permission/repository/permission-custom-repository-extension.ts @@ -5,154 +5,154 @@ import { TablePermissionDs } from '../application/data-structures/create-permiss import { PermissionEntity } from '../permission.entity.js'; export const permissionCustomRepositoryExtension = { - async saveNewOrUpdatedPermission(permissionData: PermissionEntity): Promise { - return await this.save(permissionData); - }, + async saveNewOrUpdatedPermission(permissionData: PermissionEntity): Promise { + return await this.save(permissionData); + }, - async createdDefaultAdminPermissionsInGroup(group: GroupEntity): Promise> { - const connectionAdminPermission = new PermissionEntity(); - connectionAdminPermission.groups = [group]; - connectionAdminPermission.type = PermissionTypeEnum.Connection; - connectionAdminPermission.accessLevel = AccessLevelEnum.edit; - const createdConnectionAdminPermission = await this.save(connectionAdminPermission); - const groupAdminPermission = new PermissionEntity(); - groupAdminPermission.groups = [group]; - groupAdminPermission.type = PermissionTypeEnum.Group; - groupAdminPermission.accessLevel = AccessLevelEnum.edit; - const createdGroupAdminPermission = await this.save(groupAdminPermission); - return [createdConnectionAdminPermission, createdGroupAdminPermission]; - }, + async createdDefaultAdminPermissionsInGroup(group: GroupEntity): Promise> { + const connectionAdminPermission = new PermissionEntity(); + connectionAdminPermission.groups = [group]; + connectionAdminPermission.type = PermissionTypeEnum.Connection; + connectionAdminPermission.accessLevel = AccessLevelEnum.edit; + const createdConnectionAdminPermission = await this.save(connectionAdminPermission); + const groupAdminPermission = new PermissionEntity(); + groupAdminPermission.groups = [group]; + groupAdminPermission.type = PermissionTypeEnum.Group; + groupAdminPermission.accessLevel = AccessLevelEnum.edit; + const createdGroupAdminPermission = await this.save(groupAdminPermission); + return [createdConnectionAdminPermission, createdGroupAdminPermission]; + }, - async getGroupPermissionForConnection(connectionId: string, groupId: string): Promise { - const connectionQb = this.createQueryBuilder('permission') - .leftJoinAndSelect('permission.groups', 'group') - .leftJoinAndSelect('group.connection', 'connection') - .andWhere('connection.id = :connectionId', { connectionId: connectionId }) - .andWhere('group.id = :groupId', { groupId: groupId }) - .andWhere('permission.type = :permissionType', { - permissionType: PermissionTypeEnum.Connection, - }); - const connectionPermission: PermissionEntity = await connectionQb.getOne(); - let connectionAccessLevel: AccessLevelEnum = AccessLevelEnum.none; - if (connectionPermission) { - switch (connectionPermission.accessLevel.toLowerCase()) { - case AccessLevelEnum.edit: - connectionAccessLevel = AccessLevelEnum.edit; - break; - case AccessLevelEnum.readonly: - connectionAccessLevel = AccessLevelEnum.readonly; - break; - default: - break; - } - } - return connectionAccessLevel; - }, + async getGroupPermissionForConnection(connectionId: string, groupId: string): Promise { + const connectionQb = this.createQueryBuilder('permission') + .leftJoinAndSelect('permission.groups', 'group') + .leftJoinAndSelect('group.connection', 'connection') + .andWhere('connection.id = :connectionId', { connectionId: connectionId }) + .andWhere('group.id = :groupId', { groupId: groupId }) + .andWhere('permission.type = :permissionType', { + permissionType: PermissionTypeEnum.Connection, + }); + const connectionPermission: PermissionEntity = await connectionQb.getOne(); + let connectionAccessLevel: AccessLevelEnum = AccessLevelEnum.none; + if (connectionPermission) { + switch (connectionPermission.accessLevel.toLowerCase()) { + case AccessLevelEnum.edit: + connectionAccessLevel = AccessLevelEnum.edit; + break; + case AccessLevelEnum.readonly: + connectionAccessLevel = AccessLevelEnum.readonly; + break; + default: + break; + } + } + return connectionAccessLevel; + }, - async getGroupPermissionsForGroup(connectionId: string, groupId: string): Promise { - const groupQb = this.createQueryBuilder('permission') - .leftJoinAndSelect('permission.groups', 'group') - .leftJoinAndSelect('group.connection', 'connection') - .andWhere('connection.id = :connectionId', { connectionId: connectionId }) - .andWhere('group.id = :groupId', { groupId: groupId }) - .andWhere('permission.type = :permissionType', { - permissionType: PermissionTypeEnum.Group, - }); - const groupPermission: PermissionEntity = await groupQb.getOne(); - let groupAccessLevel: AccessLevelEnum = AccessLevelEnum.none; - if (groupPermission) { - switch (groupPermission.accessLevel.toLowerCase()) { - case AccessLevelEnum.edit: - groupAccessLevel = AccessLevelEnum.edit; - break; - case AccessLevelEnum.readonly: - groupAccessLevel = AccessLevelEnum.readonly; - break; - default: - break; - } - } - return groupAccessLevel; - }, + async getGroupPermissionsForGroup(connectionId: string, groupId: string): Promise { + const groupQb = this.createQueryBuilder('permission') + .leftJoinAndSelect('permission.groups', 'group') + .leftJoinAndSelect('group.connection', 'connection') + .andWhere('connection.id = :connectionId', { connectionId: connectionId }) + .andWhere('group.id = :groupId', { groupId: groupId }) + .andWhere('permission.type = :permissionType', { + permissionType: PermissionTypeEnum.Group, + }); + const groupPermission: PermissionEntity = await groupQb.getOne(); + let groupAccessLevel: AccessLevelEnum = AccessLevelEnum.none; + if (groupPermission) { + switch (groupPermission.accessLevel.toLowerCase()) { + case AccessLevelEnum.edit: + groupAccessLevel = AccessLevelEnum.edit; + break; + case AccessLevelEnum.readonly: + groupAccessLevel = AccessLevelEnum.readonly; + break; + default: + break; + } + } + return groupAccessLevel; + }, - async getGroupPermissionsForTable( - connectionId: string, - groupId: string, - tableName: string, - ): Promise { - const tableQb = this.createQueryBuilder('permission') - .leftJoinAndSelect('permission.groups', 'group') - .leftJoinAndSelect('group.connection', 'connection') - .andWhere('connection.id = :connectionId', { connectionId: connectionId }) - .andWhere('group.id = :groupId', { groupId: groupId }) - .andWhere('permission.type = :permissionType', { - permissionType: PermissionTypeEnum.Table, - }) - .andWhere('permission.tableName = :tableName', { tableName: tableName }); - const tablePermissions: Array = await tableQb.getMany(); - return { - tableName: tableName, - accessLevel: { - add: !!tablePermissions.find((el) => el.accessLevel === AccessLevelEnum.add), - delete: !!tablePermissions.find((el) => el.accessLevel === AccessLevelEnum.delete), - edit: !!tablePermissions.find((el) => el.accessLevel === AccessLevelEnum.edit), - readonly: !!tablePermissions.find((el) => el.accessLevel === AccessLevelEnum.readonly), - visibility: !!tablePermissions.find((el) => el.accessLevel === AccessLevelEnum.visibility), - }, - }; - }, + async getGroupPermissionsForTable( + connectionId: string, + groupId: string, + tableName: string, + ): Promise { + const tableQb = this.createQueryBuilder('permission') + .leftJoinAndSelect('permission.groups', 'group') + .leftJoinAndSelect('group.connection', 'connection') + .andWhere('connection.id = :connectionId', { connectionId: connectionId }) + .andWhere('group.id = :groupId', { groupId: groupId }) + .andWhere('permission.type = :permissionType', { + permissionType: PermissionTypeEnum.Table, + }) + .andWhere('permission.tableName = :tableName', { tableName: tableName }); + const tablePermissions: Array = await tableQb.getMany(); + return { + tableName: tableName, + accessLevel: { + add: !!tablePermissions.find((el) => el.accessLevel === AccessLevelEnum.add), + delete: !!tablePermissions.find((el) => el.accessLevel === AccessLevelEnum.delete), + edit: !!tablePermissions.find((el) => el.accessLevel === AccessLevelEnum.edit), + readonly: !!tablePermissions.find((el) => el.accessLevel === AccessLevelEnum.readonly), + visibility: !!tablePermissions.find((el) => el.accessLevel === AccessLevelEnum.visibility), + }, + }; + }, - async getGroupPermissionsForAllTables(connectionId: string, groupId: string): Promise> { - const tableQb = this.createQueryBuilder('permission') - .leftJoinAndSelect('permission.groups', 'group') - .leftJoinAndSelect('group.connection', 'connection') - .andWhere('connection.id = :connectionId', { connectionId: connectionId }) - .andWhere('group.id = :groupId', { groupId: groupId }) - .andWhere('permission.type = :permissionType', { - permissionType: PermissionTypeEnum.Table, - }); - return await tableQb.getMany(); - }, + async getGroupPermissionsForAllTables(connectionId: string, groupId: string): Promise> { + const tableQb = this.createQueryBuilder('permission') + .leftJoinAndSelect('permission.groups', 'group') + .leftJoinAndSelect('group.connection', 'connection') + .andWhere('connection.id = :connectionId', { connectionId: connectionId }) + .andWhere('group.id = :groupId', { groupId: groupId }) + .andWhere('permission.type = :permissionType', { + permissionType: PermissionTypeEnum.Table, + }); + return await tableQb.getMany(); + }, - async getPermissionEntityForConnection(connectionId: string, groupId: string): Promise { - const connectionQb = this.createQueryBuilder('permission') - .leftJoinAndSelect('permission.groups', 'group') - .leftJoinAndSelect('group.connection', 'connection') - .andWhere('connection.id = :connectionId', { connectionId: connectionId }) - .andWhere('group.id = :groupId', { groupId: groupId }) - .andWhere('permission.type = :permissionType', { - permissionType: PermissionTypeEnum.Connection, - }); - return await connectionQb.getOne(); - }, + async getPermissionEntityForConnection(connectionId: string, groupId: string): Promise { + const connectionQb = this.createQueryBuilder('permission') + .leftJoinAndSelect('permission.groups', 'group') + .leftJoinAndSelect('group.connection', 'connection') + .andWhere('connection.id = :connectionId', { connectionId: connectionId }) + .andWhere('group.id = :groupId', { groupId: groupId }) + .andWhere('permission.type = :permissionType', { + permissionType: PermissionTypeEnum.Connection, + }); + return await connectionQb.getOne(); + }, - async getPermissionEntityForGroup(connectionId: string, groupId: string): Promise { - const groupQb = this.createQueryBuilder('permission') - .leftJoinAndSelect('permission.groups', 'group') - .leftJoinAndSelect('group.connection', 'connection') - .andWhere('connection.id = :connectionId', { connectionId: connectionId }) - .andWhere('group.id = :groupId', { groupId: groupId }) - .andWhere('permission.type = :permissionType', { - permissionType: PermissionTypeEnum.Group, - }); - return await groupQb.getOne(); - }, + async getPermissionEntityForGroup(connectionId: string, groupId: string): Promise { + const groupQb = this.createQueryBuilder('permission') + .leftJoinAndSelect('permission.groups', 'group') + .leftJoinAndSelect('group.connection', 'connection') + .andWhere('connection.id = :connectionId', { connectionId: connectionId }) + .andWhere('group.id = :groupId', { groupId: groupId }) + .andWhere('permission.type = :permissionType', { + permissionType: PermissionTypeEnum.Group, + }); + return await groupQb.getOne(); + }, - async getAllUserPermissionsForAllTablesInConnection( - userId: string, - connectionId: string, - ): Promise> { - const qb = this.createQueryBuilder('permission') - .leftJoin('permission.groups', 'group') - .leftJoin('group.users', 'user') - .leftJoin('group.connection', 'connection') - .andWhere('connection.id = :connectionId', { connectionId: connectionId }) - .andWhere('user.id = :userId', { userId: userId }) - .andWhere('permission.type = :permissionType', { permissionType: PermissionTypeEnum.Table }); - return await qb.getMany(); - }, + async getAllUserPermissionsForAllTablesInConnection( + userId: string, + connectionId: string, + ): Promise> { + const qb = this.createQueryBuilder('permission') + .leftJoin('permission.groups', 'group') + .leftJoin('group.users', 'user') + .leftJoin('group.connection', 'connection') + .andWhere('connection.id = :connectionId', { connectionId: connectionId }) + .andWhere('user.id = :userId', { userId: userId }) + .andWhere('permission.type = :permissionType', { permissionType: PermissionTypeEnum.Table }); + return await qb.getMany(); + }, - async removePermissionEntity(permission: PermissionEntity): Promise { - return await this.remove(permission); - }, + async removePermissionEntity(permission: PermissionEntity): Promise { + return await this.remove(permission); + }, }; diff --git a/backend/src/entities/permission/repository/permission.repository.interface.ts b/backend/src/entities/permission/repository/permission.repository.interface.ts index ce3b638b7..0a206980a 100644 --- a/backend/src/entities/permission/repository/permission.repository.interface.ts +++ b/backend/src/entities/permission/repository/permission.repository.interface.ts @@ -1,26 +1,26 @@ -import { PermissionEntity } from '../permission.entity.js'; -import { GroupEntity } from '../../group/group.entity.js'; import { AccessLevelEnum } from '../../../enums/index.js'; +import { GroupEntity } from '../../group/group.entity.js'; import { TablePermissionDs } from '../application/data-structures/create-permissions.ds.js'; +import { PermissionEntity } from '../permission.entity.js'; export interface IPermissionRepository { - saveNewOrUpdatedPermission(permissionData: PermissionEntity): Promise; + saveNewOrUpdatedPermission(permissionData: PermissionEntity): Promise; - createdDefaultAdminPermissionsInGroup(group: GroupEntity): Promise>; + createdDefaultAdminPermissionsInGroup(group: GroupEntity): Promise>; - getGroupPermissionForConnection(connectionId: string, groupId: string): Promise; + getGroupPermissionForConnection(connectionId: string, groupId: string): Promise; - getGroupPermissionsForGroup(connectionId: string, groupId: string): Promise; + getGroupPermissionsForGroup(connectionId: string, groupId: string): Promise; - getGroupPermissionsForTable(connectionId: string, groupId: string, tableName: string): Promise; + getGroupPermissionsForTable(connectionId: string, groupId: string, tableName: string): Promise; - getGroupPermissionsForAllTables(connectionId: string, groupId: string): Promise>; + getGroupPermissionsForAllTables(connectionId: string, groupId: string): Promise>; - getPermissionEntityForConnection(connectionId: string, groupId: string): Promise; + getPermissionEntityForConnection(connectionId: string, groupId: string): Promise; - getPermissionEntityForGroup(connectionId: string, groupId: string): Promise; + getPermissionEntityForGroup(connectionId: string, groupId: string): Promise; - removePermissionEntity(permission: PermissionEntity): Promise; + removePermissionEntity(permission: PermissionEntity): Promise; - getAllUserPermissionsForAllTablesInConnection(userId: string, connectionId: string): Promise>; + getAllUserPermissionsForAllTablesInConnection(userId: string, connectionId: string): Promise>; } diff --git a/backend/src/entities/permission/use-cases/create-or-update-permissions.use.case.ts b/backend/src/entities/permission/use-cases/create-or-update-permissions.use.case.ts index 615db4963..4ac71ffe0 100644 --- a/backend/src/entities/permission/use-cases/create-or-update-permissions.use.case.ts +++ b/backend/src/entities/permission/use-cases/create-or-update-permissions.use.case.ts @@ -4,187 +4,187 @@ import { IGlobalDatabaseContext } from '../../../common/application/global-datab import { BaseType } from '../../../common/data-injection.tokens.js'; import { AccessLevelEnum, PermissionTypeEnum } from '../../../enums/index.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { isObjectPropertyExists } from '../../../helpers/validators/is-object-property-exists-validator.js'; import { - CreatePermissionsDs, - PermissionsDs, - TablePermissionDs, + CreatePermissionsDs, + PermissionsDs, + TablePermissionDs, } from '../application/data-structures/create-permissions.ds.js'; import { PermissionEntity } from '../permission.entity.js'; import { buildFinalTablesPermissions } from '../utils/build-final-tables-permissions.js'; import { buildNewPermissionEntityConnection } from '../utils/build-new-permission-entity-connection.js'; import { buildNewPermissionEntityGroup } from '../utils/build-new-permission-entity-group.js'; import { ICreateOrUpdatePermissions } from './permissions-use-cases.interface.js'; -import { isObjectPropertyExists } from '../../../helpers/validators/is-object-property-exists-validator.js'; @Injectable() export class CreateOrUpdatePermissionsUseCase - extends AbstractUseCase - implements ICreateOrUpdatePermissions + extends AbstractUseCase + implements ICreateOrUpdatePermissions { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: CreatePermissionsDs): Promise { - const resultPermissions: PermissionsDs = { - connection: { - accessLevel: AccessLevelEnum.none, - connectionId: inputData.permissions.connection.connectionId, - }, - group: { - accessLevel: AccessLevelEnum.none, - groupId: inputData.permissions.group.groupId, - }, - tables: [], - }; + protected async implementation(inputData: CreatePermissionsDs): Promise { + const resultPermissions: PermissionsDs = { + connection: { + accessLevel: AccessLevelEnum.none, + connectionId: inputData.permissions.connection.connectionId, + }, + group: { + accessLevel: AccessLevelEnum.none, + groupId: inputData.permissions.group.groupId, + }, + tables: [], + }; - const { - groupId, - permissions: { - connection: { connectionId }, - }, - } = inputData; - const connectionWithThisGroup = - await this._dbContext.connectionRepository.getConnectionByGroupIdWithCompanyAndUsersInCompany(groupId); - if (connectionWithThisGroup?.id !== connectionId) { - throw new HttpException( - { - message: Messages.GROUP_NOT_FROM_THIS_CONNECTION, - }, - HttpStatus.BAD_REQUEST, - ); - } - const groupToUpdate = await this._dbContext.groupRepository.findGroupWithPermissionsById(groupId); - if (!groupToUpdate) { - throw new HttpException( - { - message: Messages.GROUP_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - if (groupToUpdate.isMain) { - throw new HttpException( - { - message: Messages.CANNOT_CHANGE_ADMIN_GROUP, - }, - HttpStatus.BAD_REQUEST, - ); - } + const { + groupId, + permissions: { + connection: { connectionId }, + }, + } = inputData; + const connectionWithThisGroup = + await this._dbContext.connectionRepository.getConnectionByGroupIdWithCompanyAndUsersInCompany(groupId); + if (connectionWithThisGroup?.id !== connectionId) { + throw new HttpException( + { + message: Messages.GROUP_NOT_FROM_THIS_CONNECTION, + }, + HttpStatus.BAD_REQUEST, + ); + } + const groupToUpdate = await this._dbContext.groupRepository.findGroupWithPermissionsById(groupId); + if (!groupToUpdate) { + throw new HttpException( + { + message: Messages.GROUP_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + if (groupToUpdate.isMain) { + throw new HttpException( + { + message: Messages.CANNOT_CHANGE_ADMIN_GROUP, + }, + HttpStatus.BAD_REQUEST, + ); + } - const [currentConnectionPermission, currentGroupPermission]: Array = await Promise.all([ - (async () => { - return await this._dbContext.permissionRepository.getPermissionEntityForConnection(connectionId, groupId); - })(), - (async () => { - return await this._dbContext.permissionRepository.getPermissionEntityForGroup(connectionId, groupId); - })(), - ]); - const allTablePermissionsInGroup = await this._dbContext.permissionRepository.getGroupPermissionsForAllTables( - connectionId, - groupId, - ); - // *** CONNECTION PERMISSION - if (currentConnectionPermission) { - const updatedPermissionData = { - type: PermissionTypeEnum.Connection, - accessLevel: inputData.permissions.connection.accessLevel, - tableName: '', - groupId: groupId, - }; - const updated = Object.assign(currentConnectionPermission, updatedPermissionData); - await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(updated); - await this._dbContext.groupRepository.saveNewOrUpdatedGroup(groupToUpdate); - resultPermissions.connection.accessLevel = updated.accessLevel; - } else { - const newPermission = buildNewPermissionEntityConnection(inputData.permissions.connection.accessLevel); - const savedPermission = await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(newPermission); - groupToUpdate.permissions.push(savedPermission); - await this._dbContext.groupRepository.saveNewOrUpdatedGroup(groupToUpdate); - resultPermissions.connection.accessLevel = newPermission.accessLevel as AccessLevelEnum; - } + const [currentConnectionPermission, currentGroupPermission]: Array = await Promise.all([ + (async () => { + return await this._dbContext.permissionRepository.getPermissionEntityForConnection(connectionId, groupId); + })(), + (async () => { + return await this._dbContext.permissionRepository.getPermissionEntityForGroup(connectionId, groupId); + })(), + ]); + const allTablePermissionsInGroup = await this._dbContext.permissionRepository.getGroupPermissionsForAllTables( + connectionId, + groupId, + ); + // *** CONNECTION PERMISSION + if (currentConnectionPermission) { + const updatedPermissionData = { + type: PermissionTypeEnum.Connection, + accessLevel: inputData.permissions.connection.accessLevel, + tableName: '', + groupId: groupId, + }; + const updated = Object.assign(currentConnectionPermission, updatedPermissionData); + await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(updated); + await this._dbContext.groupRepository.saveNewOrUpdatedGroup(groupToUpdate); + resultPermissions.connection.accessLevel = updated.accessLevel; + } else { + const newPermission = buildNewPermissionEntityConnection(inputData.permissions.connection.accessLevel); + const savedPermission = await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(newPermission); + groupToUpdate.permissions.push(savedPermission); + await this._dbContext.groupRepository.saveNewOrUpdatedGroup(groupToUpdate); + resultPermissions.connection.accessLevel = newPermission.accessLevel as AccessLevelEnum; + } - // *** GROUP PERMISSION - if (currentGroupPermission) { - const updatedPermissionData = { - type: PermissionTypeEnum.Group, - accessLevel: inputData.permissions.group.accessLevel, - tableName: '', - groupId: groupId, - }; - const updated = Object.assign(currentGroupPermission, updatedPermissionData); - await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(updated); - await this._dbContext.groupRepository.saveNewOrUpdatedGroup(groupToUpdate); - resultPermissions.group.accessLevel = updated.accessLevel; - } else { - const newPermission = buildNewPermissionEntityGroup(inputData.permissions.group.accessLevel); - const savedPermission = await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(newPermission); - groupToUpdate.permissions.push(savedPermission); - await this._dbContext.groupRepository.saveNewOrUpdatedGroup(groupToUpdate); - resultPermissions.group.accessLevel = newPermission.accessLevel as AccessLevelEnum; - } + // *** GROUP PERMISSION + if (currentGroupPermission) { + const updatedPermissionData = { + type: PermissionTypeEnum.Group, + accessLevel: inputData.permissions.group.accessLevel, + tableName: '', + groupId: groupId, + }; + const updated = Object.assign(currentGroupPermission, updatedPermissionData); + await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(updated); + await this._dbContext.groupRepository.saveNewOrUpdatedGroup(groupToUpdate); + resultPermissions.group.accessLevel = updated.accessLevel; + } else { + const newPermission = buildNewPermissionEntityGroup(inputData.permissions.group.accessLevel); + const savedPermission = await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(newPermission); + groupToUpdate.permissions.push(savedPermission); + await this._dbContext.groupRepository.saveNewOrUpdatedGroup(groupToUpdate); + resultPermissions.group.accessLevel = newPermission.accessLevel as AccessLevelEnum; + } - // *** TABLES PERMISSIONS - const tablePermissions = inputData.permissions.tables; - // delete falsy permissions - const deletedPermissions: Array = []; - await Promise.all( - tablePermissions.map(async (tablePermission: TablePermissionDs) => { - const { accessLevel, tableName } = tablePermission; - for (const key in accessLevel) { - // has own property check added to avoid object injection - // eslint-disable-next-line security/detect-object-injection - if (isObjectPropertyExists(accessLevel, key) && !accessLevel[key]) { - const permissionIndex = groupToUpdate.permissions.findIndex( - (permission: PermissionEntity) => permission.accessLevel === key && tableName === permission.tableName, - ); - if (permissionIndex >= 0) { - const permissionInGroup = groupToUpdate.permissions.at(permissionIndex); - const deletedPermission = - await this._dbContext.permissionRepository.removePermissionEntity(permissionInGroup); - deletedPermissions.push(deletedPermission); - } - } - } - }), - ); - await this._dbContext.groupRepository.saveNewOrUpdatedGroup(groupToUpdate); + // *** TABLES PERMISSIONS + const tablePermissions = inputData.permissions.tables; + // delete falsy permissions + const deletedPermissions: Array = []; + await Promise.all( + tablePermissions.map(async (tablePermission: TablePermissionDs) => { + const { accessLevel, tableName } = tablePermission; + for (const key in accessLevel) { + // has own property check added to avoid object injection + // eslint-disable-next-line security/detect-object-injection + if (isObjectPropertyExists(accessLevel, key) && !accessLevel[key]) { + const permissionIndex = groupToUpdate.permissions.findIndex( + (permission: PermissionEntity) => permission.accessLevel === key && tableName === permission.tableName, + ); + if (permissionIndex >= 0) { + const permissionInGroup = groupToUpdate.permissions.at(permissionIndex); + const deletedPermission = + await this._dbContext.permissionRepository.removePermissionEntity(permissionInGroup); + deletedPermissions.push(deletedPermission); + } + } + } + }), + ); + await this._dbContext.groupRepository.saveNewOrUpdatedGroup(groupToUpdate); - //create truthy permissions - const createdPermissions: Array = []; - await Promise.all( - tablePermissions.map(async (tablePermission: TablePermissionDs) => { - const { accessLevel, tableName } = tablePermission; - for (const key in accessLevel) { - // has own property check added to avoid object injection - // eslint-disable-next-line security/detect-object-injection - if (isObjectPropertyExists(accessLevel, key) && accessLevel[key]) { - const permissionIndex = groupToUpdate.permissions.findIndex( - (permission: PermissionEntity) => permission.accessLevel === key && tableName === permission.tableName, - ); - if (permissionIndex < 0) { - const permissionEntity = new PermissionEntity(); - permissionEntity.type = PermissionTypeEnum.Table; - permissionEntity.accessLevel = key; - permissionEntity.tableName = tableName; - groupToUpdate.permissions.push(permissionEntity); - const createdPermission = - await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(permissionEntity); - createdPermissions.push(createdPermission); - } - } - } - }), - ); - await this._dbContext.groupRepository.saveNewOrUpdatedGroup(groupToUpdate); - resultPermissions.tables = buildFinalTablesPermissions( - allTablePermissionsInGroup, - deletedPermissions, - createdPermissions, - ); - return resultPermissions; - } + //create truthy permissions + const createdPermissions: Array = []; + await Promise.all( + tablePermissions.map(async (tablePermission: TablePermissionDs) => { + const { accessLevel, tableName } = tablePermission; + for (const key in accessLevel) { + // has own property check added to avoid object injection + // eslint-disable-next-line security/detect-object-injection + if (isObjectPropertyExists(accessLevel, key) && accessLevel[key]) { + const permissionIndex = groupToUpdate.permissions.findIndex( + (permission: PermissionEntity) => permission.accessLevel === key && tableName === permission.tableName, + ); + if (permissionIndex < 0) { + const permissionEntity = new PermissionEntity(); + permissionEntity.type = PermissionTypeEnum.Table; + permissionEntity.accessLevel = key; + permissionEntity.tableName = tableName; + groupToUpdate.permissions.push(permissionEntity); + const createdPermission = + await this._dbContext.permissionRepository.saveNewOrUpdatedPermission(permissionEntity); + createdPermissions.push(createdPermission); + } + } + } + }), + ); + await this._dbContext.groupRepository.saveNewOrUpdatedGroup(groupToUpdate); + resultPermissions.tables = buildFinalTablesPermissions( + allTablePermissionsInGroup, + deletedPermissions, + createdPermissions, + ); + return resultPermissions; + } } diff --git a/backend/src/entities/permission/use-cases/permissions-use-cases.interface.ts b/backend/src/entities/permission/use-cases/permissions-use-cases.interface.ts index cbb9cd048..7c48afff1 100644 --- a/backend/src/entities/permission/use-cases/permissions-use-cases.interface.ts +++ b/backend/src/entities/permission/use-cases/permissions-use-cases.interface.ts @@ -2,5 +2,5 @@ import { InTransactionEnum } from '../../../enums/index.js'; import { CreatePermissionsDs, PermissionsDs } from '../application/data-structures/create-permissions.ds.js'; export interface ICreateOrUpdatePermissions { - execute(inputData: CreatePermissionsDs, isTransaction: InTransactionEnum): Promise; + execute(inputData: CreatePermissionsDs, isTransaction: InTransactionEnum): Promise; } diff --git a/backend/src/entities/permission/utils/build-final-tables-permissions.ts b/backend/src/entities/permission/utils/build-final-tables-permissions.ts index 5e2aab06b..2bec19262 100644 --- a/backend/src/entities/permission/utils/build-final-tables-permissions.ts +++ b/backend/src/entities/permission/utils/build-final-tables-permissions.ts @@ -1,50 +1,50 @@ -import { PermissionEntity } from '../permission.entity.js'; -import { TablePermissionDs } from '../application/data-structures/create-permissions.ds.js'; import { AccessLevelEnum } from '../../../enums/index.js'; import { getUniqArrayStrings } from '../../../helpers/index.js'; +import { TablePermissionDs } from '../application/data-structures/create-permissions.ds.js'; +import { PermissionEntity } from '../permission.entity.js'; export function buildFinalTablesPermissions( - permissionsOnStart: Array, - deletedPermissions: Array, - createdPermissions: Array, + permissionsOnStart: Array, + deletedPermissions: Array, + createdPermissions: Array, ): Array { - const filteredPermissions: Array = permissionsOnStart.filter((permission: PermissionEntity) => { - return !deletedPermissions.find((deletedPermission) => - comparePermissionsByProperties(deletedPermission, permission), - ); - }); + const filteredPermissions: Array = permissionsOnStart.filter((permission: PermissionEntity) => { + return !deletedPermissions.find((deletedPermission) => + comparePermissionsByProperties(deletedPermission, permission), + ); + }); - const totalPermissions: Array = filteredPermissions.concat(createdPermissions); - let tableNames: Array = totalPermissions.map((permission) => permission.tableName); - tableNames = getUniqArrayStrings(tableNames); - return tableNames.map((tableName): TablePermissionDs => { - return { - accessLevel: { - add: !!totalPermissions.find( - (permission) => permission.tableName === tableName && permission.accessLevel === AccessLevelEnum.add, - ), - delete: !!totalPermissions.find( - (permission) => permission.tableName === tableName && permission.accessLevel === AccessLevelEnum.delete, - ), - edit: !!totalPermissions.find( - (permission) => permission.tableName === tableName && permission.accessLevel === AccessLevelEnum.edit, - ), - readonly: !!totalPermissions.find( - (permission) => permission.tableName === tableName && permission.accessLevel === AccessLevelEnum.readonly, - ), - visibility: !!totalPermissions.find( - (permission) => permission.tableName === tableName && permission.accessLevel === AccessLevelEnum.visibility, - ), - }, - tableName: tableName, - }; - }); + const totalPermissions: Array = filteredPermissions.concat(createdPermissions); + let tableNames: Array = totalPermissions.map((permission) => permission.tableName); + tableNames = getUniqArrayStrings(tableNames); + return tableNames.map((tableName): TablePermissionDs => { + return { + accessLevel: { + add: !!totalPermissions.find( + (permission) => permission.tableName === tableName && permission.accessLevel === AccessLevelEnum.add, + ), + delete: !!totalPermissions.find( + (permission) => permission.tableName === tableName && permission.accessLevel === AccessLevelEnum.delete, + ), + edit: !!totalPermissions.find( + (permission) => permission.tableName === tableName && permission.accessLevel === AccessLevelEnum.edit, + ), + readonly: !!totalPermissions.find( + (permission) => permission.tableName === tableName && permission.accessLevel === AccessLevelEnum.readonly, + ), + visibility: !!totalPermissions.find( + (permission) => permission.tableName === tableName && permission.accessLevel === AccessLevelEnum.visibility, + ), + }, + tableName: tableName, + }; + }); } function comparePermissionsByProperties(f_permission: PermissionEntity, s_permission: PermissionEntity): boolean { - return ( - f_permission.accessLevel === s_permission.accessLevel && - f_permission.tableName === s_permission.tableName && - f_permission.type === s_permission.type - ); + return ( + f_permission.accessLevel === s_permission.accessLevel && + f_permission.tableName === s_permission.tableName && + f_permission.type === s_permission.type + ); } diff --git a/backend/src/entities/permission/utils/build-new-permission-entity-connection.ts b/backend/src/entities/permission/utils/build-new-permission-entity-connection.ts index 031a08797..18b49ac7f 100644 --- a/backend/src/entities/permission/utils/build-new-permission-entity-connection.ts +++ b/backend/src/entities/permission/utils/build-new-permission-entity-connection.ts @@ -2,8 +2,8 @@ import { AccessLevelEnum, PermissionTypeEnum } from '../../../enums/index.js'; import { PermissionEntity } from '../permission.entity.js'; export function buildNewPermissionEntityConnection(accessLevel: AccessLevelEnum): PermissionEntity { - const newPermission = new PermissionEntity(); - newPermission.type = PermissionTypeEnum.Connection; - newPermission.accessLevel = accessLevel; - return newPermission; + const newPermission = new PermissionEntity(); + newPermission.type = PermissionTypeEnum.Connection; + newPermission.accessLevel = accessLevel; + return newPermission; } diff --git a/backend/src/entities/permission/utils/build-new-permission-entity-group.ts b/backend/src/entities/permission/utils/build-new-permission-entity-group.ts index cd62f17c9..b760d7651 100644 --- a/backend/src/entities/permission/utils/build-new-permission-entity-group.ts +++ b/backend/src/entities/permission/utils/build-new-permission-entity-group.ts @@ -2,8 +2,8 @@ import { AccessLevelEnum, PermissionTypeEnum } from '../../../enums/index.js'; import { PermissionEntity } from '../permission.entity.js'; export function buildNewPermissionEntityGroup(accessLevel: AccessLevelEnum): PermissionEntity { - const newPermission = new PermissionEntity(); - newPermission.type = PermissionTypeEnum.Group; - newPermission.accessLevel = accessLevel; - return newPermission; + const newPermission = new PermissionEntity(); + newPermission.type = PermissionTypeEnum.Group; + newPermission.accessLevel = accessLevel; + return newPermission; } diff --git a/backend/src/entities/s3-widget/s3-widget.controller.ts b/backend/src/entities/s3-widget/s3-widget.controller.ts index fe490ac34..662f42c01 100644 --- a/backend/src/entities/s3-widget/s3-widget.controller.ts +++ b/backend/src/entities/s3-widget/s3-widget.controller.ts @@ -14,13 +14,13 @@ import { HttpException } from '@nestjs/common/exceptions/http.exception.js'; import { ApiBearerAuth, ApiBody, ApiOperation, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger'; import { UseCaseType } from '../../common/data-injection.tokens.js'; import { MasterPassword, QueryTableName, SlugUuid, UserId } from '../../decorators/index.js'; +import { Timeout } from '../../decorators/timeout.decorator.js'; import { InTransactionEnum } from '../../enums/index.js'; import { Messages } from '../../exceptions/text/messages.js'; import { ConnectionEditGuard, ConnectionReadGuard } from '../../guards/index.js'; import { SentryInterceptor } from '../../interceptors/index.js'; import { S3FileUrlResponseDs, S3UploadUrlResponseDs } from './application/data-structures/s3-operation.ds.js'; import { IGetS3FileUrl, IGetS3UploadUrl } from './use-cases/s3-use-cases.interface.js'; -import { Timeout } from '../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/s3-widget/s3-widget.module.ts b/backend/src/entities/s3-widget/s3-widget.module.ts index bc730e595..1b3d0be3a 100644 --- a/backend/src/entities/s3-widget/s3-widget.module.ts +++ b/backend/src/entities/s3-widget/s3-widget.module.ts @@ -5,38 +5,38 @@ import { GlobalDatabaseContext } from '../../common/application/global-database- import { BaseType, UseCaseType } from '../../common/data-injection.tokens.js'; import { LogOutEntity } from '../log-out/log-out.entity.js'; import { UserEntity } from '../user/user.entity.js'; -import { S3WidgetController } from './s3-widget.controller.js'; import { S3HelperService } from './s3-helper.service.js'; +import { S3WidgetController } from './s3-widget.controller.js'; import { GetS3FileUrlUseCase } from './use-cases/get-s3-file-url.use.case.js'; import { GetS3UploadUrlUseCase } from './use-cases/get-s3-upload-url.use.case.js'; @Module({ - imports: [TypeOrmModule.forFeature([UserEntity, LogOutEntity])], - providers: [ - S3HelperService, - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.GET_S3_FILE_URL, - useClass: GetS3FileUrlUseCase, - }, - { - provide: UseCaseType.GET_S3_UPLOAD_URL, - useClass: GetS3UploadUrlUseCase, - }, - ], - controllers: [S3WidgetController], - exports: [S3HelperService], + imports: [TypeOrmModule.forFeature([UserEntity, LogOutEntity])], + providers: [ + S3HelperService, + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.GET_S3_FILE_URL, + useClass: GetS3FileUrlUseCase, + }, + { + provide: UseCaseType.GET_S3_UPLOAD_URL, + useClass: GetS3UploadUrlUseCase, + }, + ], + controllers: [S3WidgetController], + exports: [S3HelperService], }) export class S3WidgetModule { - public configure(consumer: MiddlewareConsumer): any { - consumer - .apply(AuthMiddleware) - .forRoutes( - { path: '/s3/file/:connectionId', method: RequestMethod.GET }, - { path: '/s3/upload-url/:connectionId', method: RequestMethod.POST }, - ); - } + public configure(consumer: MiddlewareConsumer): any { + consumer + .apply(AuthMiddleware) + .forRoutes( + { path: '/s3/file/:connectionId', method: RequestMethod.GET }, + { path: '/s3/upload-url/:connectionId', method: RequestMethod.POST }, + ); + } } diff --git a/backend/src/entities/s3-widget/use-cases/get-s3-file-url.use.case.ts b/backend/src/entities/s3-widget/use-cases/get-s3-file-url.use.case.ts index b9471ec25..e633ad59c 100644 --- a/backend/src/entities/s3-widget/use-cases/get-s3-file-url.use.case.ts +++ b/backend/src/entities/s3-widget/use-cases/get-s3-file-url.use.case.ts @@ -1,6 +1,7 @@ import { HttpStatus, Inject, Injectable } from '@nestjs/common'; import { HttpException } from '@nestjs/common/exceptions/http.exception.js'; import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; +import { buildDAOsTableSettingsDs } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/table-settings.ds.builder.js'; import JSON5 from 'json5'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; @@ -13,7 +14,6 @@ import { S3FileUrlResponseDs, S3GetFileUrlDs } from '../application/data-structu import { S3WidgetParams } from '../application/data-structures/s3-widget-params.ds.js'; import { S3HelperService } from '../s3-helper.service.js'; import { IGetS3FileUrl } from './s3-use-cases.interface.js'; -import { buildDAOsTableSettingsDs } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/table-settings.ds.builder.js'; @Injectable() export class GetS3FileUrlUseCase extends AbstractUseCase implements IGetS3FileUrl { diff --git a/backend/src/entities/s3-widget/use-cases/s3-use-cases.interface.ts b/backend/src/entities/s3-widget/use-cases/s3-use-cases.interface.ts index daa3a7fa8..7a879c9ef 100644 --- a/backend/src/entities/s3-widget/use-cases/s3-use-cases.interface.ts +++ b/backend/src/entities/s3-widget/use-cases/s3-use-cases.interface.ts @@ -1,10 +1,15 @@ import { InTransactionEnum } from '../../../enums/index.js'; -import { S3FileUrlResponseDs, S3GetFileUrlDs, S3GetUploadUrlDs, S3UploadUrlResponseDs } from '../application/data-structures/s3-operation.ds.js'; +import { + S3FileUrlResponseDs, + S3GetFileUrlDs, + S3GetUploadUrlDs, + S3UploadUrlResponseDs, +} from '../application/data-structures/s3-operation.ds.js'; export interface IGetS3FileUrl { - execute(inputData: S3GetFileUrlDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: S3GetFileUrlDs, inTransaction: InTransactionEnum): Promise; } export interface IGetS3UploadUrl { - execute(inputData: S3GetUploadUrlDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: S3GetUploadUrlDs, inTransaction: InTransactionEnum): Promise; } diff --git a/backend/src/entities/secret-access-log/repository/secret-access-log-repository.extension.ts b/backend/src/entities/secret-access-log/repository/secret-access-log-repository.extension.ts index 2e6d84c00..424ea4372 100644 --- a/backend/src/entities/secret-access-log/repository/secret-access-log-repository.extension.ts +++ b/backend/src/entities/secret-access-log/repository/secret-access-log-repository.extension.ts @@ -2,38 +2,38 @@ import { SecretAccessLogEntity, SecretActionEnum } from '../secret-access-log.en import { ISecretAccessLogRepository } from './secret-access-log-repository.interface.js'; export const secretAccessLogRepositoryExtension: ISecretAccessLogRepository = { - async createAccessLog( - secretId: string, - userId: string, - action: SecretActionEnum, - success: boolean = true, - errorMessage?: string, - ): Promise { - const log = this.create({ - secretId, - userId, - action, - success, - errorMessage, - accessedAt: new Date(), - }); - return this.save(log); - }, + async createAccessLog( + secretId: string, + userId: string, + action: SecretActionEnum, + success: boolean = true, + errorMessage?: string, + ): Promise { + const log = this.create({ + secretId, + userId, + action, + success, + errorMessage, + accessedAt: new Date(), + }); + return this.save(log); + }, - async findLogsForSecret( - secretId: string, - options: { page: number; limit: number }, - ): Promise<[SecretAccessLogEntity[], number]> { - return this.findAndCount({ - where: { - secretId, - }, - relations: ['user'], - order: { - accessedAt: 'DESC', - }, - skip: (options.page - 1) * options.limit, - take: options.limit, - }); - }, + async findLogsForSecret( + secretId: string, + options: { page: number; limit: number }, + ): Promise<[SecretAccessLogEntity[], number]> { + return this.findAndCount({ + where: { + secretId, + }, + relations: ['user'], + order: { + accessedAt: 'DESC', + }, + skip: (options.page - 1) * options.limit, + take: options.limit, + }); + }, }; diff --git a/backend/src/entities/secret-access-log/repository/secret-access-log-repository.interface.ts b/backend/src/entities/secret-access-log/repository/secret-access-log-repository.interface.ts index 374bab0d4..5de960b82 100644 --- a/backend/src/entities/secret-access-log/repository/secret-access-log-repository.interface.ts +++ b/backend/src/entities/secret-access-log/repository/secret-access-log-repository.interface.ts @@ -2,17 +2,17 @@ import { Repository } from 'typeorm'; import { SecretAccessLogEntity, SecretActionEnum } from '../secret-access-log.entity.js'; export interface ISecretAccessLogRepository { - createAccessLog( - this: Repository, - secretId: string, - userId: string, - action: SecretActionEnum, - success?: boolean, - errorMessage?: string, - ): Promise; - findLogsForSecret( - this: Repository, - secretId: string, - options: { page: number; limit: number }, - ): Promise<[SecretAccessLogEntity[], number]>; + createAccessLog( + this: Repository, + secretId: string, + userId: string, + action: SecretActionEnum, + success?: boolean, + errorMessage?: string, + ): Promise; + findLogsForSecret( + this: Repository, + secretId: string, + options: { page: number; limit: number }, + ): Promise<[SecretAccessLogEntity[], number]>; } diff --git a/backend/src/entities/secret-access-log/secret-access-log.entity.ts b/backend/src/entities/secret-access-log/secret-access-log.entity.ts index 9e1cbd40e..0d2a86f26 100644 --- a/backend/src/entities/secret-access-log/secret-access-log.entity.ts +++ b/backend/src/entities/secret-access-log/secret-access-log.entity.ts @@ -1,55 +1,72 @@ -import { Column, CreateDateColumn, Entity, Index, JoinColumn, ManyToOne, PrimaryGeneratedColumn, Relation } from 'typeorm'; +import { + Column, + CreateDateColumn, + Entity, + Index, + JoinColumn, + ManyToOne, + PrimaryGeneratedColumn, + Relation, +} from 'typeorm'; import { UserEntity } from '../user/user.entity.js'; import { UserSecretEntity } from '../user-secret/user-secret.entity.js'; export enum SecretActionEnum { - CREATE = 'create', - VIEW = 'view', - COPY = 'copy', - UPDATE = 'update', - DELETE = 'delete', + CREATE = 'create', + VIEW = 'view', + COPY = 'copy', + UPDATE = 'update', + DELETE = 'delete', } @Entity('secret_access_logs') export class SecretAccessLogEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @ManyToOne(() => UserSecretEntity, (secret) => secret.accessLogs, { onDelete: 'CASCADE' }) - @JoinColumn({ name: 'secretId' }) - secret: Relation; + @ManyToOne( + () => UserSecretEntity, + (secret) => secret.accessLogs, + { onDelete: 'CASCADE' }, + ) + @JoinColumn({ name: 'secretId' }) + secret: Relation; - @Column() - @Index() - secretId: string; + @Column() + @Index() + secretId: string; - @ManyToOne(() => UserEntity, (user) => user.secretAccessLogs, { onDelete: 'CASCADE' }) - @JoinColumn({ name: 'userId' }) - user: Relation; + @ManyToOne( + () => UserEntity, + (user) => user.secretAccessLogs, + { onDelete: 'CASCADE' }, + ) + @JoinColumn({ name: 'userId' }) + user: Relation; - @Column() - @Index() - userId: string; + @Column() + @Index() + userId: string; - @Column({ - type: 'enum', - enum: SecretActionEnum, - }) - action: SecretActionEnum; + @Column({ + type: 'enum', + enum: SecretActionEnum, + }) + action: SecretActionEnum; - @CreateDateColumn() - @Index() - accessedAt: Date; + @CreateDateColumn() + @Index() + accessedAt: Date; - @Column({ type: 'varchar', length: 45, nullable: true }) - ipAddress: string; + @Column({ type: 'varchar', length: 45, nullable: true }) + ipAddress: string; - @Column({ type: 'text', nullable: true }) - userAgent: string; + @Column({ type: 'text', nullable: true }) + userAgent: string; - @Column({ default: true }) - success: boolean; + @Column({ default: true }) + success: boolean; - @Column({ type: 'text', nullable: true }) - errorMessage: string; + @Column({ type: 'text', nullable: true }) + errorMessage: string; } diff --git a/backend/src/entities/shared-jobs/shared-jobs.module.ts b/backend/src/entities/shared-jobs/shared-jobs.module.ts index 9efdb24dc..1c3d2f66c 100644 --- a/backend/src/entities/shared-jobs/shared-jobs.module.ts +++ b/backend/src/entities/shared-jobs/shared-jobs.module.ts @@ -1,22 +1,22 @@ import { Global, MiddlewareConsumer, Module } from '@nestjs/common'; -import { BaseType } from '../../common/data-injection.tokens.js'; -import { GlobalDatabaseContext } from '../../common/application/global-database-context.js'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { GlobalDatabaseContext } from '../../common/application/global-database-context.js'; +import { BaseType } from '../../common/data-injection.tokens.js'; import { SharedJobsService } from './shared-jobs.service.js'; @Global() @Module({ - imports: [TypeOrmModule.forFeature([])], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - SharedJobsService, - ], - controllers: [], - exports: [SharedJobsService], + imports: [TypeOrmModule.forFeature([])], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + SharedJobsService, + ], + controllers: [], + exports: [SharedJobsService], }) export class SharedJobsModule { - public configure(_consumer: MiddlewareConsumer): any {} + public configure(_consumer: MiddlewareConsumer): any {} } diff --git a/backend/src/entities/table-actions/table-action-events-module/action-event.entity.ts b/backend/src/entities/table-actions/table-action-events-module/action-event.entity.ts index e01187330..3e5d5a135 100644 --- a/backend/src/entities/table-actions/table-action-events-module/action-event.entity.ts +++ b/backend/src/entities/table-actions/table-action-events-module/action-event.entity.ts @@ -1,41 +1,45 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn, Relation } from 'typeorm'; import { TableActionEventEnum } from '../../../enums/table-action-event-enum.js'; -import { ActionRulesEntity } from '../table-action-rules-module/action-rules.entity.js'; import { TableActionTypeEnum } from '../../../enums/table-action-type.enum.js'; +import { ActionRulesEntity } from '../table-action-rules-module/action-rules.entity.js'; @Entity('action_events') export class ActionEventsEntity { - @PrimaryGeneratedColumn('uuid') - id: string; - - @Column('enum', { - nullable: false, - enum: TableActionEventEnum, - default: TableActionEventEnum.CUSTOM, - }) - event!: TableActionEventEnum; - - @Column('enum', { - nullable: false, - enum: TableActionTypeEnum, - default: TableActionTypeEnum.single, - }) - type!: TableActionTypeEnum; - - @Column({ default: null }) - title: string; - - @Column({ default: null }) - icon: string; - - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - created_at: Date; - - @Column({ default: false, type: 'boolean' }) - require_confirmation: boolean; - - @ManyToOne((_type) => ActionRulesEntity, (rules) => rules.table_actions, { onDelete: 'CASCADE' }) - @JoinColumn({ name: 'action_rule_id' }) - action_rule: Relation; + @PrimaryGeneratedColumn('uuid') + id: string; + + @Column('enum', { + nullable: false, + enum: TableActionEventEnum, + default: TableActionEventEnum.CUSTOM, + }) + event!: TableActionEventEnum; + + @Column('enum', { + nullable: false, + enum: TableActionTypeEnum, + default: TableActionTypeEnum.single, + }) + type!: TableActionTypeEnum; + + @Column({ default: null }) + title: string; + + @Column({ default: null }) + icon: string; + + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + created_at: Date; + + @Column({ default: false, type: 'boolean' }) + require_confirmation: boolean; + + @ManyToOne( + (_type) => ActionRulesEntity, + (rules) => rules.table_actions, + { onDelete: 'CASCADE' }, + ) + @JoinColumn({ name: 'action_rule_id' }) + action_rule: Relation; } diff --git a/backend/src/entities/table-actions/table-action-events-module/repository/action-events-custom-repository.extension.ts b/backend/src/entities/table-actions/table-action-events-module/repository/action-events-custom-repository.extension.ts index e9a5c3b7f..60d4c84cc 100644 --- a/backend/src/entities/table-actions/table-action-events-module/repository/action-events-custom-repository.extension.ts +++ b/backend/src/entities/table-actions/table-action-events-module/repository/action-events-custom-repository.extension.ts @@ -3,17 +3,17 @@ import { ActionEventsEntity } from '../action-event.entity.js'; import { IActionEventsRepository } from './action-events-custom-repository.interface.js'; export const actionEventsCustomRepositoryExtension: IActionEventsRepository = { - async saveNewOrUpdatedActionEvent(event: ActionEventsEntity): Promise { - return await this.save(event); - }, + async saveNewOrUpdatedActionEvent(event: ActionEventsEntity): Promise { + return await this.save(event); + }, - async findCustomEventsForTable(connectionId: string, tableName: string): Promise> { - return await this.createQueryBuilder('action_events') - .leftJoin('action_events.action_rule', 'action_rule') - .leftJoin('action_rule.connection', 'connection') - .where('connection.id = :connectionId', { connectionId }) - .andWhere('action_rule.table_name = :tableName', { tableName }) - .andWhere('action_events.event = :event', { event: TableActionEventEnum.CUSTOM }) - .getMany(); - }, + async findCustomEventsForTable(connectionId: string, tableName: string): Promise> { + return await this.createQueryBuilder('action_events') + .leftJoin('action_events.action_rule', 'action_rule') + .leftJoin('action_rule.connection', 'connection') + .where('connection.id = :connectionId', { connectionId }) + .andWhere('action_rule.table_name = :tableName', { tableName }) + .andWhere('action_events.event = :event', { event: TableActionEventEnum.CUSTOM }) + .getMany(); + }, }; diff --git a/backend/src/entities/table-actions/table-action-events-module/repository/action-events-custom-repository.interface.ts b/backend/src/entities/table-actions/table-action-events-module/repository/action-events-custom-repository.interface.ts index a5e20398d..979454729 100644 --- a/backend/src/entities/table-actions/table-action-events-module/repository/action-events-custom-repository.interface.ts +++ b/backend/src/entities/table-actions/table-action-events-module/repository/action-events-custom-repository.interface.ts @@ -1,7 +1,7 @@ import { ActionEventsEntity } from '../action-event.entity.js'; export interface IActionEventsRepository { - saveNewOrUpdatedActionEvent(event: ActionEventsEntity): Promise; + saveNewOrUpdatedActionEvent(event: ActionEventsEntity): Promise; - findCustomEventsForTable(connectionId: string, tableName: string): Promise>; + findCustomEventsForTable(connectionId: string, tableName: string): Promise>; } diff --git a/backend/src/entities/table-actions/table-action-events-module/utils/build-action-event-with-rule.util.ts b/backend/src/entities/table-actions/table-action-events-module/utils/build-action-event-with-rule.util.ts index 5bff78cef..aa2d35607 100644 --- a/backend/src/entities/table-actions/table-action-events-module/utils/build-action-event-with-rule.util.ts +++ b/backend/src/entities/table-actions/table-action-events-module/utils/build-action-event-with-rule.util.ts @@ -3,16 +3,16 @@ import { CreateTableActionEventDS } from '../../table-action-rules-module/applic import { ActionEventsEntity } from '../action-event.entity.js'; export function buildActionEventWithRule( - actionEventData: CreateTableActionEventDS, - actionRule: ActionRulesEntity, + actionEventData: CreateTableActionEventDS, + actionRule: ActionRulesEntity, ): ActionEventsEntity { - const { event, event_title, icon, require_confirmation, type } = actionEventData; - const newActionEvent = new ActionEventsEntity(); - newActionEvent.action_rule = actionRule; - newActionEvent.event = event; - newActionEvent.title = event_title; - newActionEvent.icon = icon; - newActionEvent.type = type; - newActionEvent.require_confirmation = require_confirmation; - return newActionEvent; + const { event, event_title, icon, require_confirmation, type } = actionEventData; + const newActionEvent = new ActionEventsEntity(); + newActionEvent.action_rule = actionRule; + newActionEvent.event = event; + newActionEvent.title = event_title; + newActionEvent.icon = icon; + newActionEvent.type = type; + newActionEvent.require_confirmation = require_confirmation; + return newActionEvent; } diff --git a/backend/src/entities/table-actions/table-action-events-module/utils/build-found-action-avent-dto.util.ts b/backend/src/entities/table-actions/table-action-events-module/utils/build-found-action-avent-dto.util.ts index c9fb149ce..75daf53f1 100644 --- a/backend/src/entities/table-actions/table-action-events-module/utils/build-found-action-avent-dto.util.ts +++ b/backend/src/entities/table-actions/table-action-events-module/utils/build-found-action-avent-dto.util.ts @@ -2,13 +2,13 @@ import { FoundActionEventDTO } from '../../table-action-rules-module/application import { ActionEventsEntity } from '../action-event.entity.js'; export function buildFoundActionEventDTO(actionEvent: ActionEventsEntity): FoundActionEventDTO { - return { - id: actionEvent.id, - event: actionEvent.event, - title: actionEvent.title, - type: actionEvent.type, - icon: actionEvent.icon, - require_confirmation: actionEvent.require_confirmation, - created_at: actionEvent.created_at, - }; + return { + id: actionEvent.id, + event: actionEvent.event, + title: actionEvent.title, + type: actionEvent.type, + icon: actionEvent.icon, + require_confirmation: actionEvent.require_confirmation, + created_at: actionEvent.created_at, + }; } diff --git a/backend/src/entities/table-actions/table-action-rules-module/action-rules.controller.ts b/backend/src/entities/table-actions/table-action-rules-module/action-rules.controller.ts index 408a2686e..026b76874 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/action-rules.controller.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/action-rules.controller.ts @@ -16,6 +16,7 @@ import { UseCaseType } from '../../../common/data-injection.tokens.js'; import { MasterPassword } from '../../../decorators/master-password.decorator.js'; import { QueryTableName } from '../../../decorators/query-table-name.decorator.js'; import { SlugUuid } from '../../../decorators/slug-uuid.decorator.js'; +import { Timeout } from '../../../decorators/timeout.decorator.js'; import { UserId } from '../../../decorators/user-id.decorator.js'; import { InTransactionEnum } from '../../../enums/in-transaction.enum.js'; import { TableActionEventEnum } from '../../../enums/table-action-event-enum.js'; @@ -47,7 +48,6 @@ import { IFindCustomEvents, IUpdateActionRule, } from './use-cases/action-rules-use-cases.interface.js'; -import { Timeout } from '../../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/table-actions/table-action-rules-module/action-rules.entity.ts b/backend/src/entities/table-actions/table-action-rules-module/action-rules.entity.ts index 0ea5e5dfe..0696b9a77 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/action-rules.entity.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/action-rules.entity.ts @@ -1,30 +1,40 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import { Column, Entity, JoinColumn, ManyToOne, OneToMany, PrimaryGeneratedColumn, Relation } from 'typeorm'; -import { TableActionEntity } from '../table-actions-module/table-action.entity.js'; -import { ActionEventsEntity } from '../table-action-events-module/action-event.entity.js'; import { ConnectionEntity } from '../../connection/connection.entity.js'; +import { ActionEventsEntity } from '../table-action-events-module/action-event.entity.js'; +import { TableActionEntity } from '../table-actions-module/table-action.entity.js'; @Entity('action_rules') export class ActionRulesEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ default: null }) - table_name: string; + @Column({ default: null }) + table_name: string; - @Column({ default: null }) - title: string; + @Column({ default: null }) + title: string; - @OneToMany((_type) => TableActionEntity, (action) => action.action_rule) - table_actions: Relation[]; + @OneToMany( + (_type) => TableActionEntity, + (action) => action.action_rule, + ) + table_actions: Relation[]; - @OneToMany((_type) => ActionEventsEntity, (event) => event.action_rule) - action_events: Relation[]; + @OneToMany( + (_type) => ActionEventsEntity, + (event) => event.action_rule, + ) + action_events: Relation[]; - @ManyToOne((_type) => ConnectionEntity, (connection) => connection.action_rules, { onDelete: 'CASCADE' }) - @JoinColumn({ name: 'connection_id' }) - connection: Relation; + @ManyToOne( + (_type) => ConnectionEntity, + (connection) => connection.action_rules, + { onDelete: 'CASCADE' }, + ) + @JoinColumn({ name: 'connection_id' }) + connection: Relation; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - created_at: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + created_at: Date; } diff --git a/backend/src/entities/table-actions/table-action-rules-module/action-rules.module.ts b/backend/src/entities/table-actions/table-action-rules-module/action-rules.module.ts index 9ed014e84..ec89eb22c 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/action-rules.module.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/action-rules.module.ts @@ -1,70 +1,70 @@ +import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthMiddleware } from '../../../authorization/auth.middleware.js'; import { GlobalDatabaseContext } from '../../../common/application/global-database-context.js'; import { BaseType, UseCaseType } from '../../../common/data-injection.tokens.js'; +import { LogOutEntity } from '../../log-out/log-out.entity.js'; +import { UserEntity } from '../../user/user.entity.js'; import { ActionRulesController } from './action-rules.controller.js'; -import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'; -import { AuthMiddleware } from '../../../authorization/auth.middleware.js'; import { ActionRulesEntity } from './action-rules.entity.js'; -import { UserEntity } from '../../user/user.entity.js'; -import { LogOutEntity } from '../../log-out/log-out.entity.js'; +import { ActivateActionsInEventUseCase } from './use-cases/activate-actions-in-rule.use.case.js'; import { CreateActionRuleUseCase } from './use-cases/create-action-rule.use.case.js'; -import { FindActionRulesForTableUseCase } from './use-cases/find-action-rules-for-table.use.case.js'; import { DeleteActionRuleWithActionsAndEventsUseCase } from './use-cases/delete-action-rule-with-actions-and-events.use.case.js'; import { FindActionRuleWithActionsAndEventsUseCase } from './use-cases/find-action-rule-with-action-and-events-by-id.use.case.js'; -import { UpdateRuleUseCase } from './use-cases/update-action-rule-with-actions-and-events.use.case.js'; +import { FindActionRulesForTableUseCase } from './use-cases/find-action-rules-for-table.use.case.js'; import { FindCustomEventsUseCase } from './use-cases/find-custom-events-use.case.js'; -import { ActivateActionsInEventUseCase } from './use-cases/activate-actions-in-rule.use.case.js'; +import { UpdateRuleUseCase } from './use-cases/update-action-rule-with-actions-and-events.use.case.js'; @Module({ - imports: [TypeOrmModule.forFeature([ActionRulesEntity, UserEntity, LogOutEntity])], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.CREATE_ACTION_RULES, - useClass: CreateActionRuleUseCase, - }, - { - provide: UseCaseType.FIND_ACTION_RULES_FOR_TABLE, - useClass: FindActionRulesForTableUseCase, - }, - { - provide: UseCaseType.DELETE_ACTION_RULE_IN_TABLE, - useClass: DeleteActionRuleWithActionsAndEventsUseCase, - }, - { - provide: UseCaseType.FIND_ACTION_RULE_BY_ID, - useClass: FindActionRuleWithActionsAndEventsUseCase, - }, - { - provide: UseCaseType.UPDATE_ACTION_RULE, - useClass: UpdateRuleUseCase, - }, - { - provide: UseCaseType.FIND_ACTION_RULE_CUSTOM_EVENTS, - useClass: FindCustomEventsUseCase, - }, - { - provide: UseCaseType.ACTIVATE_TABLE_ACTIONS_IN_EVENT, - useClass: ActivateActionsInEventUseCase, - }, - ], - controllers: [ActionRulesController], + imports: [TypeOrmModule.forFeature([ActionRulesEntity, UserEntity, LogOutEntity])], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.CREATE_ACTION_RULES, + useClass: CreateActionRuleUseCase, + }, + { + provide: UseCaseType.FIND_ACTION_RULES_FOR_TABLE, + useClass: FindActionRulesForTableUseCase, + }, + { + provide: UseCaseType.DELETE_ACTION_RULE_IN_TABLE, + useClass: DeleteActionRuleWithActionsAndEventsUseCase, + }, + { + provide: UseCaseType.FIND_ACTION_RULE_BY_ID, + useClass: FindActionRuleWithActionsAndEventsUseCase, + }, + { + provide: UseCaseType.UPDATE_ACTION_RULE, + useClass: UpdateRuleUseCase, + }, + { + provide: UseCaseType.FIND_ACTION_RULE_CUSTOM_EVENTS, + useClass: FindCustomEventsUseCase, + }, + { + provide: UseCaseType.ACTIVATE_TABLE_ACTIONS_IN_EVENT, + useClass: ActivateActionsInEventUseCase, + }, + ], + controllers: [ActionRulesController], }) export class TableTriggersModule { - public configure(consumer: MiddlewareConsumer): any { - consumer - .apply(AuthMiddleware) - .forRoutes( - { path: '/action/rule/:connectionId', method: RequestMethod.POST }, - { path: '/action/rules/:connectionId', method: RequestMethod.GET }, - { path: '/action/rule/:ruleId/:connectionId', method: RequestMethod.DELETE }, - { path: '/action/rule/:ruleId/:connectionId', method: RequestMethod.GET }, - { path: '/action/rule/:ruleId/:connectionId', method: RequestMethod.PUT }, - { path: '/action/events/custom/:connectionId', method: RequestMethod.GET }, - { path: '/event/actions/activate/:eventId/:connectionId', method: RequestMethod.POST }, - ); - } + public configure(consumer: MiddlewareConsumer): any { + consumer + .apply(AuthMiddleware) + .forRoutes( + { path: '/action/rule/:connectionId', method: RequestMethod.POST }, + { path: '/action/rules/:connectionId', method: RequestMethod.GET }, + { path: '/action/rule/:ruleId/:connectionId', method: RequestMethod.DELETE }, + { path: '/action/rule/:ruleId/:connectionId', method: RequestMethod.GET }, + { path: '/action/rule/:ruleId/:connectionId', method: RequestMethod.PUT }, + { path: '/action/events/custom/:connectionId', method: RequestMethod.GET }, + { path: '/event/actions/activate/:eventId/:connectionId', method: RequestMethod.POST }, + ); + } } diff --git a/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/activate-rule-actions.ds.ts b/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/activate-rule-actions.ds.ts index 04d972389..009543031 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/activate-rule-actions.ds.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/activate-rule-actions.ds.ts @@ -1,9 +1,9 @@ export class ActivateEventActionsDS { - connection_data: { - connectionId: string; - masterPwd: string; - userId: string; - }; - event_id: string; - request_body: Array>; + connection_data: { + connectionId: string; + masterPwd: string; + userId: string; + }; + event_id: string; + request_body: Array>; } diff --git a/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/create-action-rules.ds.ts b/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/create-action-rules.ds.ts index c5ad565c5..1aad70922 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/create-action-rules.ds.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/create-action-rules.ds.ts @@ -3,32 +3,32 @@ import { TableActionMethodEnum } from '../../../../../enums/table-action-method- import { TableActionTypeEnum } from '../../../../../enums/table-action-type.enum.js'; export class CreateTableActionData { - action_url: string; - action_method: TableActionMethodEnum; - action_slack_url: string; - action_emails: Array; + action_url: string; + action_method: TableActionMethodEnum; + action_slack_url: string; + action_emails: Array; } export class CreateTableActionEventDS { - event: TableActionEventEnum; - event_title: string; - icon: string; - require_confirmation: boolean; - type: TableActionTypeEnum; + event: TableActionEventEnum; + event_title: string; + icon: string; + require_confirmation: boolean; + type: TableActionTypeEnum; } export class CreateRuleDataDs { - rule_title: string; - table_name: string; + rule_title: string; + table_name: string; } export class CreateActionRuleDS { - rule_data: CreateRuleDataDs; - connection_data: { - connectionId: string; - masterPwd: string; - userId: string; - }; - table_actions_data: Array; - action_events_data: Array; + rule_data: CreateRuleDataDs; + connection_data: { + connectionId: string; + masterPwd: string; + userId: string; + }; + table_actions_data: Array; + action_events_data: Array; } diff --git a/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/delete-action-rule.ds.ts b/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/delete-action-rule.ds.ts index e451a8964..5db5dac51 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/delete-action-rule.ds.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/delete-action-rule.ds.ts @@ -1,4 +1,4 @@ export class FindActionRuleByIdDS { - connectionId: string; - ruleId: string; + connectionId: string; + ruleId: string; } diff --git a/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/find-all-table-triggers.ds.ts b/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/find-all-table-triggers.ds.ts index fae0fef2d..4e9a3a8e6 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/find-all-table-triggers.ds.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/find-all-table-triggers.ds.ts @@ -1,4 +1,4 @@ export class FindActionRulesDS { - connectionId: string; - tableName: string; + connectionId: string; + tableName: string; } diff --git a/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/update-action-rule.ds.ts b/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/update-action-rule.ds.ts index ef3991f83..0887c6657 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/update-action-rule.ds.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/application/data-structures/update-action-rule.ds.ts @@ -1,24 +1,24 @@ import { CreateRuleDataDs, CreateTableActionData, CreateTableActionEventDS } from './create-action-rules.ds.js'; export class UpdateRuleDataDs extends CreateRuleDataDs { - rule_id: string; + rule_id: string; } export class UpdateTableActionData extends CreateTableActionData { - action_id?: string; + action_id?: string; } export class UpdateTableActionEventDS extends CreateTableActionEventDS { - event_id?: string; + event_id?: string; } export class UpdateActionRuleDS { - rule_data: UpdateRuleDataDs; - connection_data: { - connectionId: string; - masterPwd: string; - userId: string; - }; - table_actions_data: Array; - action_events_data: Array; + rule_data: UpdateRuleDataDs; + connection_data: { + connectionId: string; + masterPwd: string; + userId: string; + }; + table_actions_data: Array; + action_events_data: Array; } diff --git a/backend/src/entities/table-actions/table-action-rules-module/application/dto/activated-table-actions.dto.ts b/backend/src/entities/table-actions/table-action-rules-module/application/dto/activated-table-actions.dto.ts index f234e671d..e0f00c142 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/application/dto/activated-table-actions.dto.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/application/dto/activated-table-actions.dto.ts @@ -2,17 +2,17 @@ import { ApiProperty } from '@nestjs/swagger'; import { OperationResultStatusEnum } from '../../../../../enums/operation-result-status.enum.js'; export class ActionActivationResultsStatusesDTO { - @ApiProperty({ type: String }) - actionId: string; + @ApiProperty({ type: String }) + actionId: string; - @ApiProperty({ enum: OperationResultStatusEnum }) - result: OperationResultStatusEnum; + @ApiProperty({ enum: OperationResultStatusEnum }) + result: OperationResultStatusEnum; } export class ActivatedTableActionsDTO { - @ApiProperty({ required: false, type: String }) - location?: string | undefined; + @ApiProperty({ required: false, type: String }) + location?: string | undefined; - @ApiProperty({ type: ActionActivationResultsStatusesDTO, isArray: true }) - activationResults: Array; + @ApiProperty({ type: ActionActivationResultsStatusesDTO, isArray: true }) + activationResults: Array; } diff --git a/backend/src/entities/table-actions/table-action-rules-module/application/dto/create-action-rules-with-actions-and-events-body.dto.ts b/backend/src/entities/table-actions/table-action-rules-module/application/dto/create-action-rules-with-actions-and-events-body.dto.ts index e3ceb504a..31ef5050e 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/application/dto/create-action-rules-with-actions-and-events-body.dto.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/application/dto/create-action-rules-with-actions-and-events-body.dto.ts @@ -1,116 +1,116 @@ +import { applyDecorators } from '@nestjs/common'; import { ApiProperty } from '@nestjs/swagger'; import { - IsArray, - IsBoolean, - IsEmail, - IsEnum, - IsNotEmpty, - IsObject, - IsOptional, - IsString, - IsUrl, - MaxLength, - MinLength, - ValidateNested, + IsArray, + IsBoolean, + IsEmail, + IsEnum, + IsNotEmpty, + IsObject, + IsOptional, + IsString, + IsUrl, + MaxLength, + MinLength, + ValidateNested, } from 'class-validator'; -import { TableActionTypeEnum } from '../../../../../enums/table-action-type.enum.js'; -import { TableActionMethodEnum } from '../../../../../enums/table-action-method-enum.js'; -import { TableActionEventEnum } from '../../../../../enums/table-action-event-enum.js'; -import { applyDecorators } from '@nestjs/common'; import { IsURLOptions } from 'validator'; +import { TableActionEventEnum } from '../../../../../enums/table-action-event-enum.js'; +import { TableActionMethodEnum } from '../../../../../enums/table-action-method-enum.js'; +import { TableActionTypeEnum } from '../../../../../enums/table-action-type.enum.js'; function IsUrlIfNotTest(validationOptions?: IsURLOptions) { - return (object: NonNullable, propertyName: string) => { - const decorators = [IsString()]; - if (process.env.NODE_ENV !== 'test') { - decorators.push(IsUrl(validationOptions)); - } - applyDecorators(...decorators)(object, propertyName); - }; + return (object: NonNullable, propertyName: string) => { + const decorators = [IsString()]; + if (process.env.NODE_ENV !== 'test') { + decorators.push(IsUrl(validationOptions)); + } + applyDecorators(...decorators)(object, propertyName); + }; } export class CreateTableActionDTO { - @ApiProperty({ type: String, required: false }) - @IsOptional() - @IsUrlIfNotTest() - url?: string; + @ApiProperty({ type: String, required: false }) + @IsOptional() + @IsUrlIfNotTest() + url?: string; - @ApiProperty({ enum: TableActionMethodEnum, required: true }) - @IsNotEmpty() - @IsEnum(TableActionMethodEnum) - method: TableActionMethodEnum; + @ApiProperty({ enum: TableActionMethodEnum, required: true }) + @IsNotEmpty() + @IsEnum(TableActionMethodEnum) + method: TableActionMethodEnum; - @ApiProperty({ type: String, required: false }) - @IsOptional() - @IsString() - @MaxLength(255) - @MinLength(1) - slack_url?: string; + @ApiProperty({ type: String, required: false }) + @IsOptional() + @IsString() + @MaxLength(255) + @MinLength(1) + slack_url?: string; - @ApiProperty({ type: String, isArray: true, required: false }) - @IsOptional() - @IsArray() - @IsString({ each: true }) - @IsEmail({}, { each: true }) - emails?: Array; + @ApiProperty({ type: String, isArray: true, required: false }) + @IsOptional() + @IsArray() + @IsString({ each: true }) + @IsEmail({}, { each: true }) + emails?: Array; } export class CreateActionEventDTO { - @ApiProperty({ enum: TableActionEventEnum }) - @IsNotEmpty() - @IsEnum(TableActionEventEnum) - event: TableActionEventEnum; + @ApiProperty({ enum: TableActionEventEnum }) + @IsNotEmpty() + @IsEnum(TableActionEventEnum) + event: TableActionEventEnum; - @ApiProperty({ enum: TableActionTypeEnum }) - @IsNotEmpty() - @IsEnum(TableActionTypeEnum) - type: TableActionTypeEnum; + @ApiProperty({ enum: TableActionTypeEnum }) + @IsNotEmpty() + @IsEnum(TableActionTypeEnum) + type: TableActionTypeEnum; - @ApiProperty() - @IsString() - @IsNotEmpty() - @MaxLength(255) - @MinLength(1) - title: string; + @ApiProperty() + @IsString() + @IsNotEmpty() + @MaxLength(255) + @MinLength(1) + title: string; - @ApiProperty({ type: String, required: false }) - @IsOptional() - @IsString() - @IsNotEmpty() - icon?: string; + @ApiProperty({ type: String, required: false }) + @IsOptional() + @IsString() + @IsNotEmpty() + icon?: string; - @ApiProperty() - @IsBoolean() - @IsNotEmpty() - require_confirmation: boolean; + @ApiProperty() + @IsBoolean() + @IsNotEmpty() + require_confirmation: boolean; } export class CreateTableActionRuleBodyDTO { - @ApiProperty() - @IsString() - @IsNotEmpty() - @MaxLength(255) - @MinLength(1) - title: string; + @ApiProperty() + @IsString() + @IsNotEmpty() + @MaxLength(255) + @MinLength(1) + title: string; - @ApiProperty() - @IsString() - @IsNotEmpty() - @MaxLength(255) - @MinLength(1) - table_name: string; + @ApiProperty() + @IsString() + @IsNotEmpty() + @MaxLength(255) + @MinLength(1) + table_name: string; - @ApiProperty({ type: CreateTableActionDTO, isArray: true }) - @IsArray() - @IsNotEmpty({ each: true }) - @IsObject({ each: true }) - @ValidateNested({ each: true }) - table_actions: Array; + @ApiProperty({ type: CreateTableActionDTO, isArray: true }) + @IsArray() + @IsNotEmpty({ each: true }) + @IsObject({ each: true }) + @ValidateNested({ each: true }) + table_actions: Array; - @ApiProperty({ type: CreateActionEventDTO, isArray: true }) - @IsArray() - @IsNotEmpty({ each: true }) - @IsObject({ each: true }) - @ValidateNested({ each: true }) - events: Array; + @ApiProperty({ type: CreateActionEventDTO, isArray: true }) + @IsArray() + @IsNotEmpty({ each: true }) + @IsObject({ each: true }) + @ValidateNested({ each: true }) + events: Array; } diff --git a/backend/src/entities/table-actions/table-action-rules-module/application/dto/found-action-rules-with-actions-and-events.dto.ts b/backend/src/entities/table-actions/table-action-rules-module/application/dto/found-action-rules-with-actions-and-events.dto.ts index 0445fbe7c..11cc5f21c 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/application/dto/found-action-rules-with-actions-and-events.dto.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/application/dto/found-action-rules-with-actions-and-events.dto.ts @@ -1,67 +1,67 @@ import { ApiProperty } from '@nestjs/swagger'; -import { TableActionTypeEnum } from '../../../../../enums/table-action-type.enum.js'; -import { TableActionMethodEnum } from '../../../../../enums/table-action-method-enum.js'; import { TableActionEventEnum } from '../../../../../enums/table-action-event-enum.js'; +import { TableActionMethodEnum } from '../../../../../enums/table-action-method-enum.js'; +import { TableActionTypeEnum } from '../../../../../enums/table-action-type.enum.js'; export class FoundTableActionDTO { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty({ type: String, nullable: true }) - url?: string | null; + @ApiProperty({ type: String, nullable: true }) + url?: string | null; - @ApiProperty({ enum: TableActionMethodEnum }) - method: TableActionMethodEnum; + @ApiProperty({ enum: TableActionMethodEnum }) + method: TableActionMethodEnum; - @ApiProperty({ type: String, nullable: true }) - slack_url?: string | null; + @ApiProperty({ type: String, nullable: true }) + slack_url?: string | null; - @ApiProperty({ type: String, isArray: true }) - emails: Array; + @ApiProperty({ type: String, isArray: true }) + emails: Array; - @ApiProperty() - created_at: Date; + @ApiProperty() + created_at: Date; } export class FoundActionEventDTO { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty({ enum: TableActionEventEnum }) - event: TableActionEventEnum; + @ApiProperty({ enum: TableActionEventEnum }) + event: TableActionEventEnum; - @ApiProperty({ enum: TableActionTypeEnum }) - type: TableActionTypeEnum; + @ApiProperty({ enum: TableActionTypeEnum }) + type: TableActionTypeEnum; - @ApiProperty() - title: string; + @ApiProperty() + title: string; - @ApiProperty({ type: String, nullable: true }) - icon: string | null; + @ApiProperty({ type: String, nullable: true }) + icon: string | null; - @ApiProperty() - require_confirmation: boolean; + @ApiProperty() + require_confirmation: boolean; - @ApiProperty() - created_at: Date; + @ApiProperty() + created_at: Date; } export class FoundActionRulesWithActionsAndEventsDTO { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - table_name: string; + @ApiProperty() + table_name: string; - @ApiProperty() - title: string; + @ApiProperty() + title: string; - @ApiProperty() - created_at: Date; + @ApiProperty() + created_at: Date; - @ApiProperty({ type: FoundTableActionDTO, isArray: true }) - table_actions: Array; + @ApiProperty({ type: FoundTableActionDTO, isArray: true }) + table_actions: Array; - @ApiProperty({ type: FoundActionEventDTO, isArray: true }) - events: Array; + @ApiProperty({ type: FoundActionEventDTO, isArray: true }) + events: Array; } diff --git a/backend/src/entities/table-actions/table-action-rules-module/application/dto/found-table-action-rules.ro.dto.ts b/backend/src/entities/table-actions/table-action-rules-module/application/dto/found-table-action-rules.ro.dto.ts index c9d933a7d..63bec1158 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/application/dto/found-table-action-rules.ro.dto.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/application/dto/found-table-action-rules.ro.dto.ts @@ -2,9 +2,9 @@ import { ApiProperty } from '@nestjs/swagger'; import { FoundActionRulesWithActionsAndEventsDTO } from './found-action-rules-with-actions-and-events.dto.js'; export class FoundTableActionRulesRoDTO { - @ApiProperty({ type: FoundActionRulesWithActionsAndEventsDTO, isArray: true }) - action_rules: Array; + @ApiProperty({ type: FoundActionRulesWithActionsAndEventsDTO, isArray: true }) + action_rules: Array; - @ApiProperty() - display_name: string; + @ApiProperty() + display_name: string; } diff --git a/backend/src/entities/table-actions/table-action-rules-module/application/dto/update-action-rule-with-actions-and-events.dto.ts b/backend/src/entities/table-actions/table-action-rules-module/application/dto/update-action-rule-with-actions-and-events.dto.ts index a85318290..304cb68ea 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/application/dto/update-action-rule-with-actions-and-events.dto.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/application/dto/update-action-rule-with-actions-and-events.dto.ts @@ -1,47 +1,47 @@ import { ApiProperty } from '@nestjs/swagger'; -import { IsString, IsNotEmpty, MaxLength, MinLength, IsArray, IsObject, IsOptional, IsUUID } from 'class-validator'; -import { CreateTableActionDTO, CreateActionEventDTO } from './create-action-rules-with-actions-and-events-body.dto.js'; +import { IsArray, IsNotEmpty, IsObject, IsOptional, IsString, IsUUID, MaxLength, MinLength } from 'class-validator'; +import { CreateActionEventDTO, CreateTableActionDTO } from './create-action-rules-with-actions-and-events-body.dto.js'; export class UpdateTableActionDTO extends CreateTableActionDTO { - @ApiProperty({ type: String, required: false }) - @IsOptional() - @IsString() - @IsUUID() - id?: string; + @ApiProperty({ type: String, required: false }) + @IsOptional() + @IsString() + @IsUUID() + id?: string; } export class UpdateActionEventDTO extends CreateActionEventDTO { - @ApiProperty({ type: String, required: false}) - @IsOptional() - @IsString() - @IsUUID() - id?: string; + @ApiProperty({ type: String, required: false }) + @IsOptional() + @IsString() + @IsUUID() + id?: string; } export class UpdateTableActionRuleBodyDTO { - @ApiProperty() - @IsString() - @IsNotEmpty() - @MaxLength(255) - @MinLength(1) - title: string; + @ApiProperty() + @IsString() + @IsNotEmpty() + @MaxLength(255) + @MinLength(1) + title: string; - @ApiProperty() - @IsString() - @IsNotEmpty() - @MaxLength(255) - @MinLength(1) - table_name: string; + @ApiProperty() + @IsString() + @IsNotEmpty() + @MaxLength(255) + @MinLength(1) + table_name: string; - @ApiProperty({ type: UpdateTableActionDTO, isArray: true}) - @IsArray() - @IsNotEmpty({ each: true }) - @IsObject({ each: true }) - table_actions: Array; + @ApiProperty({ type: UpdateTableActionDTO, isArray: true }) + @IsArray() + @IsNotEmpty({ each: true }) + @IsObject({ each: true }) + table_actions: Array; - @ApiProperty({ type: UpdateActionEventDTO, isArray: true }) - @IsArray() - @IsNotEmpty({ each: true }) - @IsObject({ each: true }) - events: Array; + @ApiProperty({ type: UpdateActionEventDTO, isArray: true }) + @IsArray() + @IsNotEmpty({ each: true }) + @IsObject({ each: true }) + events: Array; } diff --git a/backend/src/entities/table-actions/table-action-rules-module/repository/action-rules-custom-repository.interface.ts b/backend/src/entities/table-actions/table-action-rules-module/repository/action-rules-custom-repository.interface.ts index 5928a7f45..bf5a44782 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/repository/action-rules-custom-repository.interface.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/repository/action-rules-custom-repository.interface.ts @@ -1,14 +1,14 @@ import { ActionRulesEntity } from '../action-rules.entity.js'; export interface IActionRulesRepository { - saveNewOrUpdatedActionRule(rules: ActionRulesEntity): Promise; + saveNewOrUpdatedActionRule(rules: ActionRulesEntity): Promise; - findAllFullActionRulesForTableInConnection( - connectionId: string, - tableName: string, - ): Promise>; + findAllFullActionRulesForTableInConnection( + connectionId: string, + tableName: string, + ): Promise>; - findOneWithActionsAndEvents(ruleId: string, connectionId: string): Promise; + findOneWithActionsAndEvents(ruleId: string, connectionId: string): Promise; - findActionRulesWithCustomEvents(connectionId: string, tableName: string): Promise>; + findActionRulesWithCustomEvents(connectionId: string, tableName: string): Promise>; } diff --git a/backend/src/entities/table-actions/table-action-rules-module/repository/action-rules-custom-repository.ts b/backend/src/entities/table-actions/table-action-rules-module/repository/action-rules-custom-repository.ts index 39833c5de..42b9859b4 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/repository/action-rules-custom-repository.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/repository/action-rules-custom-repository.ts @@ -3,41 +3,41 @@ import { ActionRulesEntity } from '../action-rules.entity.js'; import { IActionRulesRepository } from './action-rules-custom-repository.interface.js'; export const actionRulesCustomRepositoryExtension: IActionRulesRepository = { - async saveNewOrUpdatedActionRule(triggers: ActionRulesEntity): Promise { - return await this.save(triggers); - }, + async saveNewOrUpdatedActionRule(triggers: ActionRulesEntity): Promise { + return await this.save(triggers); + }, - async findAllFullActionRulesForTableInConnection( - connectionId: string, - tableName: string, - ): Promise> { - return await this.createQueryBuilder('action_rules') - .leftJoinAndSelect('action_rules.table_actions', 'table_actions') - .leftJoinAndSelect('action_rules.action_events', 'action_events') - .leftJoinAndSelect('action_rules.connection', 'connection') - .where('connection.id = :connectionId', { connectionId }) - .andWhere('action_rules.table_name = :tableName', { tableName }) - .getMany(); - }, + async findAllFullActionRulesForTableInConnection( + connectionId: string, + tableName: string, + ): Promise> { + return await this.createQueryBuilder('action_rules') + .leftJoinAndSelect('action_rules.table_actions', 'table_actions') + .leftJoinAndSelect('action_rules.action_events', 'action_events') + .leftJoinAndSelect('action_rules.connection', 'connection') + .where('connection.id = :connectionId', { connectionId }) + .andWhere('action_rules.table_name = :tableName', { tableName }) + .getMany(); + }, - async findOneWithActionsAndEvents(ruleId: string, connectionId: string): Promise { - return await this.createQueryBuilder('action_rules') - .leftJoinAndSelect('action_rules.table_actions', 'table_actions') - .leftJoinAndSelect('action_rules.action_events', 'action_events') - .leftJoinAndSelect('action_rules.connection', 'connection') - .where('action_rules.id = :ruleId', { ruleId }) - .andWhere('connection.id = :connectionId', { connectionId }) - .getOne(); - }, + async findOneWithActionsAndEvents(ruleId: string, connectionId: string): Promise { + return await this.createQueryBuilder('action_rules') + .leftJoinAndSelect('action_rules.table_actions', 'table_actions') + .leftJoinAndSelect('action_rules.action_events', 'action_events') + .leftJoinAndSelect('action_rules.connection', 'connection') + .where('action_rules.id = :ruleId', { ruleId }) + .andWhere('connection.id = :connectionId', { connectionId }) + .getOne(); + }, - async findActionRulesWithCustomEvents(connectionId: string, tableName: string): Promise> { - return await this.createQueryBuilder('action_rules') - .leftJoinAndSelect('action_rules.table_actions', 'table_actions') - .leftJoinAndSelect('action_rules.action_events', 'action_events') - .leftJoinAndSelect('action_rules.connection', 'connection') - .where('connection.id = :connectionId', { connectionId }) - .andWhere('action_rules.table_name = :tableName', { tableName }) - .andWhere('action_events.event = :event', { event: TableActionEventEnum.CUSTOM }) - .getMany(); - }, + async findActionRulesWithCustomEvents(connectionId: string, tableName: string): Promise> { + return await this.createQueryBuilder('action_rules') + .leftJoinAndSelect('action_rules.table_actions', 'table_actions') + .leftJoinAndSelect('action_rules.action_events', 'action_events') + .leftJoinAndSelect('action_rules.connection', 'connection') + .where('connection.id = :connectionId', { connectionId }) + .andWhere('action_rules.table_name = :tableName', { tableName }) + .andWhere('action_events.event = :event', { event: TableActionEventEnum.CUSTOM }) + .getMany(); + }, }; diff --git a/backend/src/entities/table-actions/table-action-rules-module/use-cases/action-rules-use-cases.interface.ts b/backend/src/entities/table-actions/table-action-rules-module/use-cases/action-rules-use-cases.interface.ts index 07f2a2809..0e52a0f0a 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/use-cases/action-rules-use-cases.interface.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/use-cases/action-rules-use-cases.interface.ts @@ -6,44 +6,44 @@ import { FindActionRulesDS } from '../application/data-structures/find-all-table import { UpdateActionRuleDS } from '../application/data-structures/update-action-rule.ds.js'; import { ActivatedTableActionsDTO } from '../application/dto/activated-table-actions.dto.js'; import { - FoundActionEventDTO, - FoundActionRulesWithActionsAndEventsDTO, + FoundActionEventDTO, + FoundActionRulesWithActionsAndEventsDTO, } from '../application/dto/found-action-rules-with-actions-and-events.dto.js'; import { FoundTableActionRulesRoDTO } from '../application/dto/found-table-action-rules.ro.dto.js'; export interface ICreateActionRule { - execute( - inputData: CreateActionRuleDS, - inTransaction: InTransactionEnum, - ): Promise; + execute( + inputData: CreateActionRuleDS, + inTransaction: InTransactionEnum, + ): Promise; } export interface IFindActionRulesForTable { - execute(inputData: FindActionRulesDS): Promise; + execute(inputData: FindActionRulesDS): Promise; } export interface IFindCustomEvents { - execute(inputData: FindActionRulesDS): Promise>; + execute(inputData: FindActionRulesDS): Promise>; } export interface IFindActionRuleById { - execute(inputData: FindActionRuleByIdDS): Promise; + execute(inputData: FindActionRuleByIdDS): Promise; } export interface IDeleteActionRuleInTable { - execute( - inputData: FindActionRuleByIdDS, - inTransaction: InTransactionEnum, - ): Promise; + execute( + inputData: FindActionRuleByIdDS, + inTransaction: InTransactionEnum, + ): Promise; } export interface IUpdateActionRule { - execute( - inputData: UpdateActionRuleDS, - inTransaction: InTransactionEnum, - ): Promise; + execute( + inputData: UpdateActionRuleDS, + inTransaction: InTransactionEnum, + ): Promise; } export interface IActivateTableActionsInRule { - execute(inputData: ActivateEventActionsDS): Promise; + execute(inputData: ActivateEventActionsDS): Promise; } diff --git a/backend/src/entities/table-actions/table-action-rules-module/use-cases/activate-actions-in-rule.use.case.ts b/backend/src/entities/table-actions/table-action-rules-module/use-cases/activate-actions-in-rule.use.case.ts index 2429d2890..6aa5b8ac0 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/use-cases/activate-actions-in-rule.use.case.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/use-cases/activate-actions-in-rule.use.case.ts @@ -1,15 +1,15 @@ import { ForbiddenException, HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; import AbstractUseCase from '../../../../common/abstract-use.case.js'; -import { IActivateTableActionsInRule } from './action-rules-use-cases.interface.js'; -import { ActivatedTableActionsDTO } from '../application/dto/activated-table-actions.dto.js'; import { IGlobalDatabaseContext } from '../../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../../common/data-injection.tokens.js'; -import { ActivateEventActionsDS } from '../application/data-structures/activate-rule-actions.ds.js'; +import { LogOperationTypeEnum } from '../../../../enums/index.js'; import { OperationResultStatusEnum } from '../../../../enums/operation-result-status.enum.js'; import { Messages } from '../../../../exceptions/text/messages.js'; import { TableLogsService } from '../../../table-logs/table-logs.service.js'; -import { LogOperationTypeEnum } from '../../../../enums/index.js'; import { TableActionActivationService } from '../../table-actions-module/table-action-activation.service.js'; +import { ActivateEventActionsDS } from '../application/data-structures/activate-rule-actions.ds.js'; +import { ActivatedTableActionsDTO } from '../application/dto/activated-table-actions.dto.js'; +import { IActivateTableActionsInRule } from './action-rules-use-cases.interface.js'; @Injectable() export class ActivateActionsInEventUseCase diff --git a/backend/src/entities/table-actions/table-action-rules-module/use-cases/create-action-rule.use.case.ts b/backend/src/entities/table-actions/table-action-rules-module/use-cases/create-action-rule.use.case.ts index 8d91d17bd..d7db5abe3 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/use-cases/create-action-rule.use.case.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/use-cases/create-action-rule.use.case.ts @@ -1,20 +1,20 @@ import { BadRequestException, Inject, Injectable, Scope } from '@nestjs/common'; +import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import AbstractUseCase from '../../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../../common/data-injection.tokens.js'; -import { ICreateActionRule } from './action-rules-use-cases.interface.js'; -import { CreateActionRuleDS, CreateTableActionData } from '../application/data-structures/create-action-rules.ds.js'; -import { FoundActionRulesWithActionsAndEventsDTO } from '../application/dto/found-action-rules-with-actions-and-events.dto.js'; import { TableActionMethodEnum } from '../../../../enums/table-action-method-enum.js'; import { Messages } from '../../../../exceptions/text/messages.js'; -import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; -import { buildEmptyActionRule } from '../utils/build-empty-action-rule.util.js'; +import { isActionUrlHostAllowed } from '../../../../helpers/validators/is-action-url-host-allowed.js'; +import { validateStringWithEnum } from '../../../../helpers/validators/validate-string-with-enum.js'; import { ValidationHelper } from '../../../../helpers/validators/validation-helper.js'; -import { buildTableActionWithRule } from '../../table-actions-module/utils/build-table-action-with-rule.util.js'; import { buildActionEventWithRule } from '../../table-action-events-module/utils/build-action-event-with-rule.util.js'; +import { buildTableActionWithRule } from '../../table-actions-module/utils/build-table-action-with-rule.util.js'; +import { CreateActionRuleDS, CreateTableActionData } from '../application/data-structures/create-action-rules.ds.js'; +import { FoundActionRulesWithActionsAndEventsDTO } from '../application/dto/found-action-rules-with-actions-and-events.dto.js'; +import { buildEmptyActionRule } from '../utils/build-empty-action-rule.util.js'; import { buildFoundActionRulesWithActionsAndEventsDTO } from '../utils/build-found-action-rules-with-actions-and-events-dto.util.js'; -import { validateStringWithEnum } from '../../../../helpers/validators/validate-string-with-enum.js'; -import { isActionUrlHostAllowed } from '../../../../helpers/validators/is-action-url-host-allowed.js'; +import { ICreateActionRule } from './action-rules-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class CreateActionRuleUseCase diff --git a/backend/src/entities/table-actions/table-action-rules-module/use-cases/delete-action-rule-with-actions-and-events.use.case.ts b/backend/src/entities/table-actions/table-action-rules-module/use-cases/delete-action-rule-with-actions-and-events.use.case.ts index 728d2d091..22bc77066 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/use-cases/delete-action-rule-with-actions-and-events.use.case.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/use-cases/delete-action-rule-with-actions-and-events.use.case.ts @@ -1,39 +1,39 @@ import { Inject, Injectable, NotFoundException, Scope } from '@nestjs/common'; import AbstractUseCase from '../../../../common/abstract-use.case.js'; -import { FindActionRuleByIdDS } from '../application/data-structures/delete-action-rule.ds.js'; -import { FoundActionRulesWithActionsAndEventsDTO } from '../application/dto/found-action-rules-with-actions-and-events.dto.js'; -import { IDeleteActionRuleInTable } from './action-rules-use-cases.interface.js'; -import { BaseType } from '../../../../common/data-injection.tokens.js'; import { IGlobalDatabaseContext } from '../../../../common/application/global-database-context.interface.js'; +import { BaseType } from '../../../../common/data-injection.tokens.js'; import { Messages } from '../../../../exceptions/text/messages.js'; +import { FindActionRuleByIdDS } from '../application/data-structures/delete-action-rule.ds.js'; +import { FoundActionRulesWithActionsAndEventsDTO } from '../application/dto/found-action-rules-with-actions-and-events.dto.js'; import { buildFoundActionRulesWithActionsAndEventsDTO } from '../utils/build-found-action-rules-with-actions-and-events-dto.util.js'; +import { IDeleteActionRuleInTable } from './action-rules-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class DeleteActionRuleWithActionsAndEventsUseCase - extends AbstractUseCase - implements IDeleteActionRuleInTable + extends AbstractUseCase + implements IDeleteActionRuleInTable { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - public async implementation(inputData: FindActionRuleByIdDS): Promise { - const { connectionId, ruleId } = inputData; - const foundRuleWithActionsAndEvents = await this._dbContext.actionRulesRepository.findOneWithActionsAndEvents( - ruleId, - connectionId, - ); - if (!foundRuleWithActionsAndEvents) { - throw new NotFoundException(Messages.RULE_NOT_FOUND); - } - const foundRuleCopy = { ...foundRuleWithActionsAndEvents }; - const { table_actions, action_events } = foundRuleWithActionsAndEvents; - await this._dbContext.tableActionRepository.remove(table_actions); - await this._dbContext.actionEventsRepository.remove(action_events); - await this._dbContext.actionRulesRepository.remove(foundRuleWithActionsAndEvents); - return buildFoundActionRulesWithActionsAndEventsDTO(foundRuleCopy); - } + public async implementation(inputData: FindActionRuleByIdDS): Promise { + const { connectionId, ruleId } = inputData; + const foundRuleWithActionsAndEvents = await this._dbContext.actionRulesRepository.findOneWithActionsAndEvents( + ruleId, + connectionId, + ); + if (!foundRuleWithActionsAndEvents) { + throw new NotFoundException(Messages.RULE_NOT_FOUND); + } + const foundRuleCopy = { ...foundRuleWithActionsAndEvents }; + const { table_actions, action_events } = foundRuleWithActionsAndEvents; + await this._dbContext.tableActionRepository.remove(table_actions); + await this._dbContext.actionEventsRepository.remove(action_events); + await this._dbContext.actionRulesRepository.remove(foundRuleWithActionsAndEvents); + return buildFoundActionRulesWithActionsAndEventsDTO(foundRuleCopy); + } } diff --git a/backend/src/entities/table-actions/table-action-rules-module/use-cases/find-action-rule-with-action-and-events-by-id.use.case.ts b/backend/src/entities/table-actions/table-action-rules-module/use-cases/find-action-rule-with-action-and-events-by-id.use.case.ts index 872bdf414..c9cfd10c0 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/use-cases/find-action-rule-with-action-and-events-by-id.use.case.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/use-cases/find-action-rule-with-action-and-events-by-id.use.case.ts @@ -1,34 +1,34 @@ import { Inject, Injectable, NotFoundException } from '@nestjs/common'; import AbstractUseCase from '../../../../common/abstract-use.case.js'; -import { FindActionRuleByIdDS } from '../application/data-structures/delete-action-rule.ds.js'; -import { FoundActionRulesWithActionsAndEventsDTO } from '../application/dto/found-action-rules-with-actions-and-events.dto.js'; -import { IFindActionRuleById } from './action-rules-use-cases.interface.js'; import { IGlobalDatabaseContext } from '../../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../../common/data-injection.tokens.js'; import { Messages } from '../../../../exceptions/text/messages.js'; +import { FindActionRuleByIdDS } from '../application/data-structures/delete-action-rule.ds.js'; +import { FoundActionRulesWithActionsAndEventsDTO } from '../application/dto/found-action-rules-with-actions-and-events.dto.js'; import { buildFoundActionRulesWithActionsAndEventsDTO } from '../utils/build-found-action-rules-with-actions-and-events-dto.util.js'; +import { IFindActionRuleById } from './action-rules-use-cases.interface.js'; @Injectable() export class FindActionRuleWithActionsAndEventsUseCase - extends AbstractUseCase - implements IFindActionRuleById + extends AbstractUseCase + implements IFindActionRuleById { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - public async implementation(inputData: FindActionRuleByIdDS): Promise { - const { connectionId, ruleId } = inputData; - const foundRuleWithActionsAndEvents = await this._dbContext.actionRulesRepository.findOneWithActionsAndEvents( - ruleId, - connectionId, - ); - if (!foundRuleWithActionsAndEvents) { - throw new NotFoundException(Messages.RULE_NOT_FOUND); - } - return buildFoundActionRulesWithActionsAndEventsDTO(foundRuleWithActionsAndEvents); - } + public async implementation(inputData: FindActionRuleByIdDS): Promise { + const { connectionId, ruleId } = inputData; + const foundRuleWithActionsAndEvents = await this._dbContext.actionRulesRepository.findOneWithActionsAndEvents( + ruleId, + connectionId, + ); + if (!foundRuleWithActionsAndEvents) { + throw new NotFoundException(Messages.RULE_NOT_FOUND); + } + return buildFoundActionRulesWithActionsAndEventsDTO(foundRuleWithActionsAndEvents); + } } diff --git a/backend/src/entities/table-actions/table-action-rules-module/use-cases/find-action-rules-for-table.use.case.ts b/backend/src/entities/table-actions/table-action-rules-module/use-cases/find-action-rules-for-table.use.case.ts index a498d5182..7f8e407b9 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/use-cases/find-action-rules-for-table.use.case.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/use-cases/find-action-rules-for-table.use.case.ts @@ -1,35 +1,35 @@ import { Inject, Injectable } from '@nestjs/common'; import AbstractUseCase from '../../../../common/abstract-use.case.js'; -import { FindActionRulesDS } from '../application/data-structures/find-all-table-triggers.ds.js'; -import { IFindActionRulesForTable } from './action-rules-use-cases.interface.js'; import { IGlobalDatabaseContext } from '../../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../../common/data-injection.tokens.js'; -import { buildFoundActionRulesWithActionsAndEventsDTO } from '../utils/build-found-action-rules-with-actions-and-events-dto.util.js'; +import { FindActionRulesDS } from '../application/data-structures/find-all-table-triggers.ds.js'; import { FoundTableActionRulesRoDTO } from '../application/dto/found-table-action-rules.ro.dto.js'; +import { buildFoundActionRulesWithActionsAndEventsDTO } from '../utils/build-found-action-rules-with-actions-and-events-dto.util.js'; +import { IFindActionRulesForTable } from './action-rules-use-cases.interface.js'; @Injectable() export class FindActionRulesForTableUseCase - extends AbstractUseCase - implements IFindActionRulesForTable + extends AbstractUseCase + implements IFindActionRulesForTable { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - public async implementation(inputData: FindActionRulesDS): Promise { - const { connectionId, tableName } = inputData; - const foundActionRules = await this._dbContext.actionRulesRepository.findAllFullActionRulesForTableInConnection( - connectionId, - tableName, - ); - const foundTableSettings = await this._dbContext.tableSettingsRepository.findTableSettings(connectionId, tableName); - const display_name = foundTableSettings?.display_name ?? tableName; - return { - display_name: display_name, - action_rules: foundActionRules.map((actionRule) => buildFoundActionRulesWithActionsAndEventsDTO(actionRule)), - }; - } + public async implementation(inputData: FindActionRulesDS): Promise { + const { connectionId, tableName } = inputData; + const foundActionRules = await this._dbContext.actionRulesRepository.findAllFullActionRulesForTableInConnection( + connectionId, + tableName, + ); + const foundTableSettings = await this._dbContext.tableSettingsRepository.findTableSettings(connectionId, tableName); + const display_name = foundTableSettings?.display_name ?? tableName; + return { + display_name: display_name, + action_rules: foundActionRules.map((actionRule) => buildFoundActionRulesWithActionsAndEventsDTO(actionRule)), + }; + } } diff --git a/backend/src/entities/table-actions/table-action-rules-module/use-cases/find-custom-events-use.case.ts b/backend/src/entities/table-actions/table-action-rules-module/use-cases/find-custom-events-use.case.ts index fb1f6a2da..52360e8a6 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/use-cases/find-custom-events-use.case.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/use-cases/find-custom-events-use.case.ts @@ -1,30 +1,30 @@ import { Inject, Injectable } from '@nestjs/common'; import AbstractUseCase from '../../../../common/abstract-use.case.js'; -import { FindActionRulesDS } from '../application/data-structures/find-all-table-triggers.ds.js'; -import { FoundActionEventDTO } from '../application/dto/found-action-rules-with-actions-and-events.dto.js'; -import { IFindCustomEvents } from './action-rules-use-cases.interface.js'; import { IGlobalDatabaseContext } from '../../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../../common/data-injection.tokens.js'; +import { FindActionRulesDS } from '../application/data-structures/find-all-table-triggers.ds.js'; +import { FoundActionEventDTO } from '../application/dto/found-action-rules-with-actions-and-events.dto.js'; import { buildActionEventDto } from '../utils/build-found-action-event-dto.util.js'; +import { IFindCustomEvents } from './action-rules-use-cases.interface.js'; @Injectable() export class FindCustomEventsUseCase - extends AbstractUseCase> - implements IFindCustomEvents + extends AbstractUseCase> + implements IFindCustomEvents { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - public async implementation(inputData: FindActionRulesDS): Promise> { - const { connectionId, tableName } = inputData; - const foundRuleEvents = await this._dbContext.actionEventsRepository.findCustomEventsForTable( - connectionId, - tableName, - ); - return foundRuleEvents.map((actionEvent) => buildActionEventDto(actionEvent)); - } + public async implementation(inputData: FindActionRulesDS): Promise> { + const { connectionId, tableName } = inputData; + const foundRuleEvents = await this._dbContext.actionEventsRepository.findCustomEventsForTable( + connectionId, + tableName, + ); + return foundRuleEvents.map((actionEvent) => buildActionEventDto(actionEvent)); + } } diff --git a/backend/src/entities/table-actions/table-action-rules-module/use-cases/update-action-rule-with-actions-and-events.use.case.ts b/backend/src/entities/table-actions/table-action-rules-module/use-cases/update-action-rule-with-actions-and-events.use.case.ts index 34acbce7d..1b7b29918 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/use-cases/update-action-rule-with-actions-and-events.use.case.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/use-cases/update-action-rule-with-actions-and-events.use.case.ts @@ -1,20 +1,20 @@ import { BadRequestException, Inject, Injectable, Scope } from '@nestjs/common'; -import { IUpdateActionRule } from './action-rules-use-cases.interface.js'; +import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import AbstractUseCase from '../../../../common/abstract-use.case.js'; -import { UpdateActionRuleDS } from '../application/data-structures/update-action-rule.ds.js'; -import { FoundActionRulesWithActionsAndEventsDTO } from '../application/dto/found-action-rules-with-actions-and-events.dto.js'; import { IGlobalDatabaseContext } from '../../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../../common/data-injection.tokens.js'; -import { Messages } from '../../../../exceptions/text/messages.js'; -import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import { TableActionMethodEnum } from '../../../../enums/table-action-method-enum.js'; +import { Messages } from '../../../../exceptions/text/messages.js'; +import { isActionUrlHostAllowed } from '../../../../helpers/validators/is-action-url-host-allowed.js'; +import { validateStringWithEnum } from '../../../../helpers/validators/validate-string-with-enum.js'; import { ValidationHelper } from '../../../../helpers/validators/validation-helper.js'; -import { CreateTableActionData } from '../application/data-structures/create-action-rules.ds.js'; -import { buildTableActionWithRule } from '../../table-actions-module/utils/build-table-action-with-rule.util.js'; import { buildActionEventWithRule } from '../../table-action-events-module/utils/build-action-event-with-rule.util.js'; +import { buildTableActionWithRule } from '../../table-actions-module/utils/build-table-action-with-rule.util.js'; +import { CreateTableActionData } from '../application/data-structures/create-action-rules.ds.js'; +import { UpdateActionRuleDS } from '../application/data-structures/update-action-rule.ds.js'; +import { FoundActionRulesWithActionsAndEventsDTO } from '../application/dto/found-action-rules-with-actions-and-events.dto.js'; import { buildFoundActionRulesWithActionsAndEventsDTO } from '../utils/build-found-action-rules-with-actions-and-events-dto.util.js'; -import { validateStringWithEnum } from '../../../../helpers/validators/validate-string-with-enum.js'; -import { isActionUrlHostAllowed } from '../../../../helpers/validators/is-action-url-host-allowed.js'; +import { IUpdateActionRule } from './action-rules-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class UpdateRuleUseCase diff --git a/backend/src/entities/table-actions/table-action-rules-module/utils/build-empty-action-rule.util.ts b/backend/src/entities/table-actions/table-action-rules-module/utils/build-empty-action-rule.util.ts index 358a82ab3..a2fa76c21 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/utils/build-empty-action-rule.util.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/utils/build-empty-action-rule.util.ts @@ -3,11 +3,11 @@ import { ActionRulesEntity } from '../action-rules.entity.js'; import { CreateRuleDataDs } from '../application/data-structures/create-action-rules.ds.js'; export function buildEmptyActionRule(ruleData: CreateRuleDataDs, connection: ConnectionEntity): ActionRulesEntity { - const newActionRule = new ActionRulesEntity(); - newActionRule.title = ruleData.rule_title; - newActionRule.table_name = ruleData.table_name; - newActionRule.action_events = []; - newActionRule.table_actions = []; - newActionRule.connection = connection; - return newActionRule; + const newActionRule = new ActionRulesEntity(); + newActionRule.title = ruleData.rule_title; + newActionRule.table_name = ruleData.table_name; + newActionRule.action_events = []; + newActionRule.table_actions = []; + newActionRule.connection = connection; + return newActionRule; } diff --git a/backend/src/entities/table-actions/table-action-rules-module/utils/build-found-action-event-dto.util.ts b/backend/src/entities/table-actions/table-action-rules-module/utils/build-found-action-event-dto.util.ts index ce2830039..6f8b77d8d 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/utils/build-found-action-event-dto.util.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/utils/build-found-action-event-dto.util.ts @@ -2,13 +2,13 @@ import { ActionEventsEntity } from '../../table-action-events-module/action-even import { FoundActionEventDTO } from '../application/dto/found-action-rules-with-actions-and-events.dto.js'; export function buildActionEventDto(actionEvent: ActionEventsEntity): FoundActionEventDTO { - return { - id: actionEvent.id, - event: actionEvent.event, - title: actionEvent.title, - type: actionEvent.type, - icon: actionEvent.icon, - require_confirmation: actionEvent.require_confirmation, - created_at: actionEvent.created_at, - }; + return { + id: actionEvent.id, + event: actionEvent.event, + title: actionEvent.title, + type: actionEvent.type, + icon: actionEvent.icon, + require_confirmation: actionEvent.require_confirmation, + created_at: actionEvent.created_at, + }; } diff --git a/backend/src/entities/table-actions/table-action-rules-module/utils/build-found-action-rules-with-actions-and-events-dto.util.ts b/backend/src/entities/table-actions/table-action-rules-module/utils/build-found-action-rules-with-actions-and-events-dto.util.ts index 9805bc98a..3395cce24 100644 --- a/backend/src/entities/table-actions/table-action-rules-module/utils/build-found-action-rules-with-actions-and-events-dto.util.ts +++ b/backend/src/entities/table-actions/table-action-rules-module/utils/build-found-action-rules-with-actions-and-events-dto.util.ts @@ -4,14 +4,14 @@ import { ActionRulesEntity } from '../action-rules.entity.js'; import { FoundActionRulesWithActionsAndEventsDTO } from '../application/dto/found-action-rules-with-actions-and-events.dto.js'; export function buildFoundActionRulesWithActionsAndEventsDTO( - actionRule: ActionRulesEntity, + actionRule: ActionRulesEntity, ): FoundActionRulesWithActionsAndEventsDTO { - return { - id: actionRule.id, - table_name: actionRule.table_name, - created_at: actionRule.created_at, - title: actionRule.title, - table_actions: actionRule.table_actions.map((tableAction) => buildFoundTableActionDTO(tableAction)), - events: actionRule.action_events.map((actionEvent) => buildFoundActionEventDTO(actionEvent)), - }; + return { + id: actionRule.id, + table_name: actionRule.table_name, + created_at: actionRule.created_at, + title: actionRule.title, + table_actions: actionRule.table_actions.map((tableAction) => buildFoundTableActionDTO(tableAction)), + events: actionRule.action_events.map((actionEvent) => buildFoundActionEventDTO(actionEvent)), + }; } diff --git a/backend/src/entities/table-actions/table-actions-module/dto/create-table-action.dto.ts b/backend/src/entities/table-actions/table-actions-module/dto/create-table-action.dto.ts index 7192854af..b5938073d 100644 --- a/backend/src/entities/table-actions/table-actions-module/dto/create-table-action.dto.ts +++ b/backend/src/entities/table-actions/table-actions-module/dto/create-table-action.dto.ts @@ -1,32 +1,32 @@ import { ApiProperty } from '@nestjs/swagger'; -import { TableActionTypeEnum } from '../../../../enums/index.js'; import { IsArray, IsEmail, IsEnum, IsOptional, IsString } from 'class-validator'; +import { TableActionTypeEnum } from '../../../../enums/index.js'; import { TableActionMethodEnum } from '../../../../enums/table-action-method-enum.js'; export class CreateTableActionDTO { - @ApiProperty({ enum: TableActionTypeEnum }) - @IsEnum(TableActionTypeEnum) - type: TableActionTypeEnum; + @ApiProperty({ enum: TableActionTypeEnum }) + @IsEnum(TableActionTypeEnum) + type: TableActionTypeEnum; - @ApiProperty() - @IsOptional() - @IsString() - url: string; + @ApiProperty() + @IsOptional() + @IsString() + url: string; - @ApiProperty({ enum: TableActionMethodEnum }) - @IsOptional() - @IsEnum(TableActionMethodEnum) - method: TableActionMethodEnum; + @ApiProperty({ enum: TableActionMethodEnum }) + @IsOptional() + @IsEnum(TableActionMethodEnum) + method: TableActionMethodEnum; - @ApiProperty() - @IsOptional() - @IsString() - slack_url: string; + @ApiProperty() + @IsOptional() + @IsString() + slack_url: string; - @ApiProperty() - @IsOptional() - @IsArray() - @IsString({ each: true }) - @IsEmail({}, { each: true }) - emails: string[]; + @ApiProperty() + @IsOptional() + @IsArray() + @IsString({ each: true }) + @IsEmail({}, { each: true }) + emails: string[]; } diff --git a/backend/src/entities/table-actions/table-actions-module/repository/table-action-custom-repository.interface.ts b/backend/src/entities/table-actions/table-actions-module/repository/table-action-custom-repository.interface.ts index b4ee30c6e..11a865dfa 100644 --- a/backend/src/entities/table-actions/table-actions-module/repository/table-action-custom-repository.interface.ts +++ b/backend/src/entities/table-actions/table-actions-module/repository/table-action-custom-repository.interface.ts @@ -1,24 +1,24 @@ import { TableActionEntity } from '../table-action.entity.js'; export interface ITableActionRepository { - saveNewOrUpdatedTableAction(action: TableActionEntity): Promise; + saveNewOrUpdatedTableAction(action: TableActionEntity): Promise; - findTableActionById(actionId: string): Promise; + findTableActionById(actionId: string): Promise; - deleteTableAction(action: TableActionEntity): Promise; + deleteTableAction(action: TableActionEntity): Promise; - findTableActionsByIds(actionIds: Array): Promise>; + findTableActionsByIds(actionIds: Array): Promise>; - findTableActionsWithRulesAndEvents(connectionId: string, tableName: string): Promise>; + findTableActionsWithRulesAndEvents(connectionId: string, tableName: string): Promise>; - findActionsWithCustomEventsByEventIdConnectionId( - eventId: string, - connectionId: string, - ): Promise>; + findActionsWithCustomEventsByEventIdConnectionId( + eventId: string, + connectionId: string, + ): Promise>; - findTableActionsWithAddRowEvents(connectionId: string, tableName: string): Promise>; + findTableActionsWithAddRowEvents(connectionId: string, tableName: string): Promise>; - findTableActionsWithUpdateRowEvents(connectionId: string, tableName: string): Promise>; + findTableActionsWithUpdateRowEvents(connectionId: string, tableName: string): Promise>; - findTableActionsWithDeleteRowEvents(connectionId: string, tableName: string): Promise>; + findTableActionsWithDeleteRowEvents(connectionId: string, tableName: string): Promise>; } diff --git a/backend/src/entities/table-actions/table-actions-module/repository/table-actions-custom-repository.extension.ts b/backend/src/entities/table-actions/table-actions-module/repository/table-actions-custom-repository.extension.ts index 3e3d584a0..28438b267 100644 --- a/backend/src/entities/table-actions/table-actions-module/repository/table-actions-custom-repository.extension.ts +++ b/backend/src/entities/table-actions/table-actions-module/repository/table-actions-custom-repository.extension.ts @@ -3,86 +3,92 @@ import { TableActionEntity } from '../table-action.entity.js'; import { ITableActionRepository } from './table-action-custom-repository.interface.js'; export const tableActionsCustomRepositoryExtension: ITableActionRepository = { - async saveNewOrUpdatedTableAction(action: TableActionEntity): Promise { - return await this.save(action); - }, + async saveNewOrUpdatedTableAction(action: TableActionEntity): Promise { + return await this.save(action); + }, - async findTableActionsWithRulesAndEvents(connectionId: string, tableName: string): Promise> { - const qb = this.createQueryBuilder('table_actions') - .leftJoinAndSelect('table_actions.action_rule', 'action_rule') - .leftJoinAndSelect('action_rule.connection', 'connection') - .leftJoinAndSelect('action_rule.action_events', 'action_events') - .leftJoinAndSelect('table_actions.settings', 'table_settings') - .where('connection.id = :connectionId', { connectionId }) - .andWhere('action_rule.table_name = :tableName', { tableName }); - return await qb.getMany(); - }, + async findTableActionsWithRulesAndEvents(connectionId: string, tableName: string): Promise> { + const qb = this.createQueryBuilder('table_actions') + .leftJoinAndSelect('table_actions.action_rule', 'action_rule') + .leftJoinAndSelect('action_rule.connection', 'connection') + .leftJoinAndSelect('action_rule.action_events', 'action_events') + .leftJoinAndSelect('table_actions.settings', 'table_settings') + .where('connection.id = :connectionId', { connectionId }) + .andWhere('action_rule.table_name = :tableName', { tableName }); + return await qb.getMany(); + }, - async findTableActionsWithAddRowEvents(connectionId: string, tableName: string): Promise> { - const qb = this.createQueryBuilder('table_actions') - .leftJoinAndSelect('table_actions.action_rule', 'action_rule') - .leftJoinAndSelect('action_rule.connection', 'connection') - .leftJoinAndSelect('action_rule.action_events', 'action_events') - .leftJoinAndSelect('table_actions.settings', 'table_settings') - .where('connection.id = :connectionId', { connectionId }) - .andWhere('action_rule.table_name = :tableName', { tableName }) - .andWhere('action_events.event = :eventType', { eventType: TableActionEventEnum.ADD_ROW }); - return await qb.getMany(); - }, + async findTableActionsWithAddRowEvents(connectionId: string, tableName: string): Promise> { + const qb = this.createQueryBuilder('table_actions') + .leftJoinAndSelect('table_actions.action_rule', 'action_rule') + .leftJoinAndSelect('action_rule.connection', 'connection') + .leftJoinAndSelect('action_rule.action_events', 'action_events') + .leftJoinAndSelect('table_actions.settings', 'table_settings') + .where('connection.id = :connectionId', { connectionId }) + .andWhere('action_rule.table_name = :tableName', { tableName }) + .andWhere('action_events.event = :eventType', { eventType: TableActionEventEnum.ADD_ROW }); + return await qb.getMany(); + }, - async findTableActionsWithUpdateRowEvents(connectionId: string, tableName: string): Promise> { - const qb = this.createQueryBuilder('table_actions') - .leftJoinAndSelect('table_actions.action_rule', 'action_rule') - .leftJoinAndSelect('action_rule.connection', 'connection') - .leftJoinAndSelect('action_rule.action_events', 'action_events') - .leftJoinAndSelect('table_actions.settings', 'table_settings') - .where('connection.id = :connectionId', { connectionId }) - .andWhere('action_rule.table_name = :tableName', { tableName }) - .andWhere('action_events.event = :eventType', { eventType: TableActionEventEnum.UPDATE_ROW }); - return qb.getMany(); - }, + async findTableActionsWithUpdateRowEvents( + connectionId: string, + tableName: string, + ): Promise> { + const qb = this.createQueryBuilder('table_actions') + .leftJoinAndSelect('table_actions.action_rule', 'action_rule') + .leftJoinAndSelect('action_rule.connection', 'connection') + .leftJoinAndSelect('action_rule.action_events', 'action_events') + .leftJoinAndSelect('table_actions.settings', 'table_settings') + .where('connection.id = :connectionId', { connectionId }) + .andWhere('action_rule.table_name = :tableName', { tableName }) + .andWhere('action_events.event = :eventType', { eventType: TableActionEventEnum.UPDATE_ROW }); + return qb.getMany(); + }, - async findTableActionsWithDeleteRowEvents(connectionId: string, tableName: string): Promise> { - const qb = this.createQueryBuilder('table_actions') - .leftJoinAndSelect('table_actions.action_rule', 'action_rule') - .leftJoinAndSelect('action_rule.connection', 'connection') - .leftJoinAndSelect('action_rule.action_events', 'action_events') - .leftJoinAndSelect('table_actions.settings', 'table_settings') - .where('connection.id = :connectionId', { connectionId }) - .andWhere('action_rule.table_name = :tableName', { tableName }) - .andWhere('action_events.event = :eventType', { eventType: TableActionEventEnum.DELETE_ROW }); - return qb.getMany(); - }, + async findTableActionsWithDeleteRowEvents( + connectionId: string, + tableName: string, + ): Promise> { + const qb = this.createQueryBuilder('table_actions') + .leftJoinAndSelect('table_actions.action_rule', 'action_rule') + .leftJoinAndSelect('action_rule.connection', 'connection') + .leftJoinAndSelect('action_rule.action_events', 'action_events') + .leftJoinAndSelect('table_actions.settings', 'table_settings') + .where('connection.id = :connectionId', { connectionId }) + .andWhere('action_rule.table_name = :tableName', { tableName }) + .andWhere('action_events.event = :eventType', { eventType: TableActionEventEnum.DELETE_ROW }); + return qb.getMany(); + }, - async findActionsWithCustomEventsByEventIdConnectionId( - eventId: string, - connectionId: string, - ): Promise> { - const qb = this.createQueryBuilder('table_actions') - .leftJoinAndSelect('table_actions.action_rule', 'action_rule') - .leftJoinAndSelect('action_rule.connection', 'connection') - .leftJoinAndSelect('action_rule.action_events', 'action_events') - .where('connection.id = :connectionId', { connectionId }) - .andWhere('action_events.id = :eventId', { eventId }) - .andWhere('action_events.event = :eventType', { eventType: TableActionEventEnum.CUSTOM }); - return await qb.getMany(); - }, + async findActionsWithCustomEventsByEventIdConnectionId( + eventId: string, + connectionId: string, + ): Promise> { + const qb = this.createQueryBuilder('table_actions') + .leftJoinAndSelect('table_actions.action_rule', 'action_rule') + .leftJoinAndSelect('action_rule.connection', 'connection') + .leftJoinAndSelect('action_rule.action_events', 'action_events') + .where('connection.id = :connectionId', { connectionId }) + .andWhere('action_events.id = :eventId', { eventId }) + .andWhere('action_events.event = :eventType', { eventType: TableActionEventEnum.CUSTOM }); + return await qb.getMany(); + }, - async findTableActionById(actionId: string): Promise { - return await this.findOne({ where: { id: actionId } }); - }, + async findTableActionById(actionId: string): Promise { + return await this.findOne({ where: { id: actionId } }); + }, - async deleteTableAction(action: TableActionEntity): Promise { - await this.createQueryBuilder('table_actions') - .delete() - .from(TableActionEntity) - .where('id = :id', { id: action.id }) - .execute(); - return action; - }, + async deleteTableAction(action: TableActionEntity): Promise { + await this.createQueryBuilder('table_actions') + .delete() + .from(TableActionEntity) + .where('id = :id', { id: action.id }) + .execute(); + return action; + }, - async findTableActionsByIds(actionIds: Array): Promise> { - const qb = this.createQueryBuilder('table_actions').where('table_actions.id IN (:...actionIds)', { actionIds }); - return await qb.getMany(); - }, + async findTableActionsByIds(actionIds: Array): Promise> { + const qb = this.createQueryBuilder('table_actions').where('table_actions.id IN (:...actionIds)', { actionIds }); + return await qb.getMany(); + }, }; diff --git a/backend/src/entities/table-actions/table-actions-module/table-action-activation.service.ts b/backend/src/entities/table-actions/table-actions-module/table-action-activation.service.ts index 1566f1a34..855809762 100644 --- a/backend/src/entities/table-actions/table-actions-module/table-action-activation.service.ts +++ b/backend/src/entities/table-actions/table-actions-module/table-action-activation.service.ts @@ -1,343 +1,343 @@ import { HttpException, Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; -import { Repository } from 'typeorm'; -import { UserEntity } from '../../user/user.entity.js'; -import { TableActionEntity } from './table-action.entity.js'; -import { ConnectionEntity } from '../../connection/connection.entity.js'; -import { TableActionEventEnum } from '../../../enums/table-action-event-enum.js'; -import { TableActionMethodEnum } from '../../../enums/table-action-method-enum.js'; -import { OperationResultStatusEnum } from '../../../enums/operation-result-status.enum.js'; import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; -import { actionSlackPostMessage } from '../../../helpers/slack/action-slack-post-message.js'; -import { Encryptor } from '../../../helpers/encryption/encryptor.js'; import axios, { AxiosResponse } from 'axios'; import PQueue from 'p-queue'; +import { Repository } from 'typeorm'; +import { OperationResultStatusEnum } from '../../../enums/operation-result-status.enum.js'; +import { TableActionEventEnum } from '../../../enums/table-action-event-enum.js'; +import { TableActionMethodEnum } from '../../../enums/table-action-method-enum.js'; import { isSaaS } from '../../../helpers/app/is-saas.js'; -import { escapeHtml } from '../../email/utils/escape-html.util.js'; -import { EmailService } from '../../email/email/email.service.js'; +import { Encryptor } from '../../../helpers/encryption/encryptor.js'; +import { actionSlackPostMessage } from '../../../helpers/slack/action-slack-post-message.js'; import { isObjectPropertyExists } from '../../../helpers/validators/is-object-property-exists-validator.js'; +import { ConnectionEntity } from '../../connection/connection.entity.js'; +import { EmailService } from '../../email/email/email.service.js'; +import { escapeHtml } from '../../email/utils/escape-html.util.js'; +import { UserEntity } from '../../user/user.entity.js'; +import { TableActionEntity } from './table-action.entity.js'; export type ActionActivationResult = { - location?: string; - receivedOperationResult: OperationResultStatusEnum; - receivedPrimaryKeysObj: Array>; + location?: string; + receivedOperationResult: OperationResultStatusEnum; + receivedPrimaryKeysObj: Array>; }; export type UserInfoMessageData = { - userId: string; - email: string; - userName: string; + userId: string; + email: string; + userName: string; }; @Injectable() export class TableActionActivationService { - constructor( - @InjectRepository(UserEntity) - private readonly userRepository: Repository, - private readonly emailService: EmailService, - ) {} + constructor( + @InjectRepository(UserEntity) + private readonly userRepository: Repository, + private readonly emailService: EmailService, + ) {} - public async activateTableAction( - tableAction: TableActionEntity, - foundConnection: ConnectionEntity, - request_body: Array>, - userId: string, - tableName: string, - triggerOperation: TableActionEventEnum, - ): Promise { - const foundUser = await this.userRepository.findOne({ - where: { id: userId }, - }); - const userInfoMessageData: UserInfoMessageData = { - userId, - email: foundUser.email, - userName: foundUser.name, - }; - switch (tableAction.method) { - case TableActionMethodEnum.URL: - return await this.activateHttpTableAction( - tableAction, - foundConnection, - request_body, - userInfoMessageData, - tableName, - ); - case TableActionMethodEnum.SLACK: - return await this.activateSlackTableAction( - tableAction, - foundConnection, - request_body, - userInfoMessageData, - tableName, - triggerOperation, - ); - case TableActionMethodEnum.EMAIL: - return await this.activateEmailTableAction( - tableAction, - foundConnection, - request_body, - userInfoMessageData, - tableName, - triggerOperation, - ); - default: - throw new Error(`Method ${tableAction.method} is not supported`); - } - } + public async activateTableAction( + tableAction: TableActionEntity, + foundConnection: ConnectionEntity, + request_body: Array>, + userId: string, + tableName: string, + triggerOperation: TableActionEventEnum, + ): Promise { + const foundUser = await this.userRepository.findOne({ + where: { id: userId }, + }); + const userInfoMessageData: UserInfoMessageData = { + userId, + email: foundUser.email, + userName: foundUser.name, + }; + switch (tableAction.method) { + case TableActionMethodEnum.URL: + return await this.activateHttpTableAction( + tableAction, + foundConnection, + request_body, + userInfoMessageData, + tableName, + ); + case TableActionMethodEnum.SLACK: + return await this.activateSlackTableAction( + tableAction, + foundConnection, + request_body, + userInfoMessageData, + tableName, + triggerOperation, + ); + case TableActionMethodEnum.EMAIL: + return await this.activateEmailTableAction( + tableAction, + foundConnection, + request_body, + userInfoMessageData, + tableName, + triggerOperation, + ); + default: + throw new Error(`Method ${tableAction.method} is not supported`); + } + } - public async activateSlackTableAction( - tableAction: TableActionEntity, - foundConnection: ConnectionEntity, - request_body: Array>, - userInfo: UserInfoMessageData, - tableName: string, - triggerOperation?: TableActionEventEnum, - ): Promise { - let operationResult = OperationResultStatusEnum.unknown; - const primaryKeyValuesArray: Array> = await this.getPrimaryKeysObjects( - foundConnection, - request_body, - tableName, - ); + public async activateSlackTableAction( + tableAction: TableActionEntity, + foundConnection: ConnectionEntity, + request_body: Array>, + userInfo: UserInfoMessageData, + tableName: string, + triggerOperation?: TableActionEventEnum, + ): Promise { + let operationResult = OperationResultStatusEnum.unknown; + const primaryKeyValuesArray: Array> = await this.getPrimaryKeysObjects( + foundConnection, + request_body, + tableName, + ); - const slackMessage = this.generateMessageContent(userInfo, triggerOperation, tableName, primaryKeyValuesArray); + const slackMessage = this.generateMessageContent(userInfo, triggerOperation, tableName, primaryKeyValuesArray); - try { - await actionSlackPostMessage(slackMessage, tableAction.slack_url); - operationResult = OperationResultStatusEnum.successfully; - } catch (_e) { - operationResult = OperationResultStatusEnum.unsuccessfully; - } - return { - receivedOperationResult: operationResult, - receivedPrimaryKeysObj: primaryKeyValuesArray, - }; - } + try { + await actionSlackPostMessage(slackMessage, tableAction.slack_url); + operationResult = OperationResultStatusEnum.successfully; + } catch (_e) { + operationResult = OperationResultStatusEnum.unsuccessfully; + } + return { + receivedOperationResult: operationResult, + receivedPrimaryKeysObj: primaryKeyValuesArray, + }; + } - public async activateEmailTableAction( - tableAction: TableActionEntity, - foundConnection: ConnectionEntity, - request_body: Array>, - userInfo: UserInfoMessageData, - tableName: string, - triggerOperation: TableActionEventEnum, - ): Promise { - let operationResult = OperationResultStatusEnum.unknown; - const primaryKeyValuesArray: Array> = await this.getPrimaryKeysObjects( - foundConnection, - request_body, - tableName, - ); - const queue = new PQueue({ concurrency: 2 }); - try { - await Promise.all( - tableAction.emails.map((email) => - queue.add(() => { - return this.emailService.sendEmailActionToUser( - email, - userInfo, - triggerOperation, - tableName, - primaryKeyValuesArray, - ); - }), - ), - ); - operationResult = OperationResultStatusEnum.successfully; - return { - receivedOperationResult: operationResult, - receivedPrimaryKeysObj: primaryKeyValuesArray, - }; - } catch (_error) { - operationResult = OperationResultStatusEnum.unsuccessfully; - return { - receivedOperationResult: operationResult, - receivedPrimaryKeysObj: primaryKeyValuesArray, - }; - } - } + public async activateEmailTableAction( + tableAction: TableActionEntity, + foundConnection: ConnectionEntity, + request_body: Array>, + userInfo: UserInfoMessageData, + tableName: string, + triggerOperation: TableActionEventEnum, + ): Promise { + let operationResult = OperationResultStatusEnum.unknown; + const primaryKeyValuesArray: Array> = await this.getPrimaryKeysObjects( + foundConnection, + request_body, + tableName, + ); + const queue = new PQueue({ concurrency: 2 }); + try { + await Promise.all( + tableAction.emails.map((email) => + queue.add(() => { + return this.emailService.sendEmailActionToUser( + email, + userInfo, + triggerOperation, + tableName, + primaryKeyValuesArray, + ); + }), + ), + ); + operationResult = OperationResultStatusEnum.successfully; + return { + receivedOperationResult: operationResult, + receivedPrimaryKeysObj: primaryKeyValuesArray, + }; + } catch (_error) { + operationResult = OperationResultStatusEnum.unsuccessfully; + return { + receivedOperationResult: operationResult, + receivedPrimaryKeysObj: primaryKeyValuesArray, + }; + } + } - public async activateHttpTableAction( - tableAction: TableActionEntity, - foundConnection: ConnectionEntity, - request_body: Array>, - userInfo: UserInfoMessageData, - tableName: string, - ): Promise { - const { userId } = userInfo; - let operationResult = OperationResultStatusEnum.unknown; + public async activateHttpTableAction( + tableAction: TableActionEntity, + foundConnection: ConnectionEntity, + request_body: Array>, + userInfo: UserInfoMessageData, + tableName: string, + ): Promise { + const { userId } = userInfo; + let operationResult = OperationResultStatusEnum.unknown; - const primaryKeyValuesArray: Array> = await this.getPrimaryKeysObjects( - foundConnection, - request_body, - tableName, - ); + const primaryKeyValuesArray: Array> = await this.getPrimaryKeysObjects( + foundConnection, + request_body, + tableName, + ); - const dateString = new Date().toISOString(); - const actionRequestBody = JSON.stringify({ - $$_raUserId: userId, - primaryKeys: primaryKeyValuesArray, - $$_date: dateString, - $$_actionId: tableAction.id, - $$_tableName: tableName, - }); - const autoadminSignatureHeader = Encryptor.hashDataHMACexternalKey(foundConnection.signing_key, actionRequestBody); + const dateString = new Date().toISOString(); + const actionRequestBody = JSON.stringify({ + $$_raUserId: userId, + primaryKeys: primaryKeyValuesArray, + $$_date: dateString, + $$_actionId: tableAction.id, + $$_tableName: tableName, + }); + const autoadminSignatureHeader = Encryptor.hashDataHMACexternalKey(foundConnection.signing_key, actionRequestBody); - let result: AxiosResponse; - try { - result = await axios.post(tableAction.url, actionRequestBody, { - headers: { 'Rocketadmin-Signature': autoadminSignatureHeader, 'Content-Type': 'application/json' }, - maxRedirects: 0, - validateStatus: (status) => status <= 599, - }); - if (!isSaaS()) { - console.info('HTTP action result data', result.data); - console.info('HTTP action result status', result.status); - console.info('HTTP action result headers', result.headers); - } - } catch (error) { - if (axios.isAxiosError(error)) { - const errorMessage = - result?.data?.error || - result?.data?.message || - result?.data?.errorMessage || - result?.data?.response || - 'An error occurred'; - const responseStatus = error.response?.status || result?.status || 500; - throw new HttpException( - { - message: errorMessage, - }, - responseStatus, - ); - } - throw error; - } - const operationStatusCode = result.status; - if (operationStatusCode >= 200 && operationStatusCode < 300) { - operationResult = OperationResultStatusEnum.successfully; - return { - receivedOperationResult: operationResult, - receivedPrimaryKeysObj: primaryKeyValuesArray, - }; - } - if (operationStatusCode >= 300 && operationStatusCode < 400) { - operationResult = OperationResultStatusEnum.successfully; - return { - receivedOperationResult: operationResult, - location: result?.headers?.location, - receivedPrimaryKeysObj: primaryKeyValuesArray, - }; - } - if (operationStatusCode >= 400 && operationStatusCode <= 599) { - const errorMessage = - result?.data?.error || - result?.data?.message || - result?.data?.errorMessage || - result?.data?.response || - 'An error occurred'; - throw new HttpException( - { - message: errorMessage, - }, - operationStatusCode, - ); - } - return { - receivedOperationResult: operationResult, - receivedPrimaryKeysObj: primaryKeyValuesArray, - }; - } + let result: AxiosResponse; + try { + result = await axios.post(tableAction.url, actionRequestBody, { + headers: { 'Rocketadmin-Signature': autoadminSignatureHeader, 'Content-Type': 'application/json' }, + maxRedirects: 0, + validateStatus: (status) => status <= 599, + }); + if (!isSaaS()) { + console.info('HTTP action result data', result.data); + console.info('HTTP action result status', result.status); + console.info('HTTP action result headers', result.headers); + } + } catch (error) { + if (axios.isAxiosError(error)) { + const errorMessage = + result?.data?.error || + result?.data?.message || + result?.data?.errorMessage || + result?.data?.response || + 'An error occurred'; + const responseStatus = error.response?.status || result?.status || 500; + throw new HttpException( + { + message: errorMessage, + }, + responseStatus, + ); + } + throw error; + } + const operationStatusCode = result.status; + if (operationStatusCode >= 200 && operationStatusCode < 300) { + operationResult = OperationResultStatusEnum.successfully; + return { + receivedOperationResult: operationResult, + receivedPrimaryKeysObj: primaryKeyValuesArray, + }; + } + if (operationStatusCode >= 300 && operationStatusCode < 400) { + operationResult = OperationResultStatusEnum.successfully; + return { + receivedOperationResult: operationResult, + location: result?.headers?.location, + receivedPrimaryKeysObj: primaryKeyValuesArray, + }; + } + if (operationStatusCode >= 400 && operationStatusCode <= 599) { + const errorMessage = + result?.data?.error || + result?.data?.message || + result?.data?.errorMessage || + result?.data?.response || + 'An error occurred'; + throw new HttpException( + { + message: errorMessage, + }, + operationStatusCode, + ); + } + return { + receivedOperationResult: operationResult, + receivedPrimaryKeysObj: primaryKeyValuesArray, + }; + } - public async activateTableActions( - tableActions: Array, - connection: ConnectionEntity, - request_body: Record, - userId: string, - tableName: string, - triggerOperation: TableActionEventEnum, - ): Promise { - if (!tableActions.length) { - return; - } - try { - const queue = new PQueue({ concurrency: 2 }); - await Promise.all( - tableActions.map((tableAction) => - queue - .add(() => - this.activateTableAction(tableAction, connection, [request_body], userId, tableName, triggerOperation), - ) - .catch((error) => { - console.error('Error in activateTableActions', error); - }), - ), - ); - } catch (_error) { - return; - } - } + public async activateTableActions( + tableActions: Array, + connection: ConnectionEntity, + request_body: Record, + userId: string, + tableName: string, + triggerOperation: TableActionEventEnum, + ): Promise { + if (!tableActions.length) { + return; + } + try { + const queue = new PQueue({ concurrency: 2 }); + await Promise.all( + tableActions.map((tableAction) => + queue + .add(() => + this.activateTableAction(tableAction, connection, [request_body], userId, tableName, triggerOperation), + ) + .catch((error) => { + console.error('Error in activateTableActions', error); + }), + ), + ); + } catch (_error) { + return; + } + } - private async getPrimaryKeysObjects( - foundConnection: ConnectionEntity, - request_body: Array>, - tableName: string, - ): Promise>> { - const dataAccessObject = getDataAccessObject(foundConnection); - const tablePrimaryKeys = await dataAccessObject.getTablePrimaryColumns(tableName, null); - const primaryKeyValuesArray: Array> = []; - for (const primaryKeyInBody of request_body) { - const pKeysObj: Record = {}; - for (const primaryKey of tablePrimaryKeys) { - if ( - isObjectPropertyExists(primaryKeyInBody, primaryKey.column_name) && - primaryKeyInBody[primaryKey.column_name] - ) { - pKeysObj[primaryKey.column_name] = primaryKeyInBody[primaryKey.column_name]; - } - } - if (Object.keys(pKeysObj).length) { - primaryKeyValuesArray.push(pKeysObj); - } - } + private async getPrimaryKeysObjects( + foundConnection: ConnectionEntity, + request_body: Array>, + tableName: string, + ): Promise>> { + const dataAccessObject = getDataAccessObject(foundConnection); + const tablePrimaryKeys = await dataAccessObject.getTablePrimaryColumns(tableName, null); + const primaryKeyValuesArray: Array> = []; + for (const primaryKeyInBody of request_body) { + const pKeysObj: Record = {}; + for (const primaryKey of tablePrimaryKeys) { + if ( + isObjectPropertyExists(primaryKeyInBody, primaryKey.column_name) && + primaryKeyInBody[primaryKey.column_name] + ) { + pKeysObj[primaryKey.column_name] = primaryKeyInBody[primaryKey.column_name]; + } + } + if (Object.keys(pKeysObj).length) { + primaryKeyValuesArray.push(pKeysObj); + } + } - return primaryKeyValuesArray; - } + return primaryKeyValuesArray; + } - private escapePrimaryKeyValuesArray(array: Array>): Array> { - return array.map((record) => { - const escapedRecord: Record = {}; - for (const key in record) { - if (isObjectPropertyExists(record, key)) { - const escapedKey = escapeHtml(key); - // eslint-disable-next-line security/detect-object-injection - const value = record[key]; - const escapedValue = typeof value === 'string' ? escapeHtml(value) : value; - // eslint-disable-next-line security/detect-object-injection - escapedRecord[escapedKey] = escapedValue; - } - } - return escapedRecord; - }); - } + private escapePrimaryKeyValuesArray(array: Array>): Array> { + return array.map((record) => { + const escapedRecord: Record = {}; + for (const key in record) { + if (isObjectPropertyExists(record, key)) { + const escapedKey = escapeHtml(key); + // eslint-disable-next-line security/detect-object-injection + const value = record[key]; + const escapedValue = typeof value === 'string' ? escapeHtml(value) : value; + // eslint-disable-next-line security/detect-object-injection + escapedRecord[escapedKey] = escapedValue; + } + } + return escapedRecord; + }); + } - private generateMessageContent( - userInfo: UserInfoMessageData, - triggerOperation: TableActionEventEnum, - tableName: string, - primaryKeyValuesArray: Array>, - ): string { - const { email, userId, userName } = userInfo; - const action = - triggerOperation === TableActionEventEnum.ADD_ROW - ? 'added a row' - : triggerOperation === TableActionEventEnum.UPDATE_ROW - ? 'updated a row' - : triggerOperation === TableActionEventEnum.DELETE_ROW - ? 'deleted a row' - : 'performed an action'; - primaryKeyValuesArray = this.escapePrimaryKeyValuesArray(primaryKeyValuesArray); - const textContent = `${userName ? escapeHtml(userName) : 'User'} (email: ${email}, user id: ${userId}) has ${action} in the table "${escapeHtml(tableName)}".`; - return `${textContent} Primary Keys: ${JSON.stringify(primaryKeyValuesArray)}`; - } + private generateMessageContent( + userInfo: UserInfoMessageData, + triggerOperation: TableActionEventEnum, + tableName: string, + primaryKeyValuesArray: Array>, + ): string { + const { email, userId, userName } = userInfo; + const action = + triggerOperation === TableActionEventEnum.ADD_ROW + ? 'added a row' + : triggerOperation === TableActionEventEnum.UPDATE_ROW + ? 'updated a row' + : triggerOperation === TableActionEventEnum.DELETE_ROW + ? 'deleted a row' + : 'performed an action'; + primaryKeyValuesArray = this.escapePrimaryKeyValuesArray(primaryKeyValuesArray); + const textContent = `${userName ? escapeHtml(userName) : 'User'} (email: ${email}, user id: ${userId}) has ${action} in the table "${escapeHtml(tableName)}".`; + return `${textContent} Primary Keys: ${JSON.stringify(primaryKeyValuesArray)}`; + } } diff --git a/backend/src/entities/table-actions/table-actions-module/table-action.entity.ts b/backend/src/entities/table-actions/table-actions-module/table-action.entity.ts index 485ee9213..1e8edeb3f 100644 --- a/backend/src/entities/table-actions/table-actions-module/table-action.entity.ts +++ b/backend/src/entities/table-actions/table-actions-module/table-action.entity.ts @@ -1,67 +1,75 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ import { - AfterLoad, - BeforeInsert, - BeforeUpdate, - Column, - Entity, - JoinColumn, - ManyToOne, - PrimaryGeneratedColumn, - Relation, + AfterLoad, + BeforeInsert, + BeforeUpdate, + Column, + Entity, + JoinColumn, + ManyToOne, + PrimaryGeneratedColumn, + Relation, } from 'typeorm'; -import { TableSettingsEntity } from '../../table-settings/common-table-settings/table-settings.entity.js'; -import { ActionRulesEntity } from '../table-action-rules-module/action-rules.entity.js'; import { TableActionMethodEnum } from '../../../enums/table-action-method-enum.js'; import { Encryptor } from '../../../helpers/encryption/encryptor.js'; - +import { TableSettingsEntity } from '../../table-settings/common-table-settings/table-settings.entity.js'; +import { ActionRulesEntity } from '../table-action-rules-module/action-rules.entity.js'; + @Entity('table_actions') export class TableActionEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ default: null }) - url: string; + @Column({ default: null }) + url: string; - @Column('enum', { - nullable: false, - enum: TableActionMethodEnum, - default: TableActionMethodEnum.URL, - }) - method!: TableActionMethodEnum; + @Column('enum', { + nullable: false, + enum: TableActionMethodEnum, + default: TableActionMethodEnum.URL, + }) + method!: TableActionMethodEnum; - @Column({ default: null }) - slack_url: string; + @Column({ default: null }) + slack_url: string; - @Column('varchar', { array: true, default: {} }) - emails: string[]; + @Column('varchar', { array: true, default: {} }) + emails: string[]; - @ManyToOne((_type) => TableSettingsEntity, (settings) => settings.table_actions, { onDelete: 'CASCADE' }) - settings: Relation; + @ManyToOne( + (_type) => TableSettingsEntity, + (settings) => settings.table_actions, + { onDelete: 'CASCADE' }, + ) + settings: Relation; - @ManyToOne((_type) => ActionRulesEntity, (rules) => rules.table_actions, { onDelete: 'CASCADE' }) - @JoinColumn({ name: 'action_rule_id' }) - action_rule: Relation; + @ManyToOne( + (_type) => ActionRulesEntity, + (rules) => rules.table_actions, + { onDelete: 'CASCADE' }, + ) + @JoinColumn({ name: 'action_rule_id' }) + action_rule: Relation; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - created_at: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + created_at: Date; - @BeforeInsert() - encryptSlackUrl(): void { - if (this.slack_url) { - this.slack_url = Encryptor.encryptData(this.slack_url); - } - } + @BeforeInsert() + encryptSlackUrl(): void { + if (this.slack_url) { + this.slack_url = Encryptor.encryptData(this.slack_url); + } + } - @BeforeUpdate() - encryptEmailsAndTokensBeforeUpdate(): void { - this.encryptSlackUrl(); - } + @BeforeUpdate() + encryptEmailsAndTokensBeforeUpdate(): void { + this.encryptSlackUrl(); + } - @AfterLoad() - decryptSlackUrl(): void { - if (this.slack_url) { - this.slack_url = Encryptor.decryptData(this.slack_url); - } - } + @AfterLoad() + decryptSlackUrl(): void { + if (this.slack_url) { + this.slack_url = Encryptor.decryptData(this.slack_url); + } + } } diff --git a/backend/src/entities/table-actions/table-actions-module/table-action.module.ts b/backend/src/entities/table-actions/table-actions-module/table-action.module.ts index b4ea466bc..60c392c7c 100644 --- a/backend/src/entities/table-actions/table-actions-module/table-action.module.ts +++ b/backend/src/entities/table-actions/table-actions-module/table-action.module.ts @@ -10,18 +10,18 @@ import { TableActionActivationService } from './table-action-activation.service. @Global() @Module({ - imports: [TypeOrmModule.forFeature([TableActionEntity, UserEntity, LogOutEntity])], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - TableActionActivationService, - ], - exports: [TableActionActivationService], + imports: [TypeOrmModule.forFeature([TableActionEntity, UserEntity, LogOutEntity])], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + TableActionActivationService, + ], + exports: [TableActionActivationService], }) export class TableActionModule implements NestModule { - public configure(consumer: MiddlewareConsumer): any { - consumer.apply(AuthMiddleware).forRoutes(); - } + public configure(consumer: MiddlewareConsumer): any { + consumer.apply(AuthMiddleware).forRoutes(); + } } diff --git a/backend/src/entities/table-actions/table-actions-module/utils/build-found-table-action-dto.util.ts b/backend/src/entities/table-actions/table-actions-module/utils/build-found-table-action-dto.util.ts index 2c3330648..04d3e46e2 100644 --- a/backend/src/entities/table-actions/table-actions-module/utils/build-found-table-action-dto.util.ts +++ b/backend/src/entities/table-actions/table-actions-module/utils/build-found-table-action-dto.util.ts @@ -2,12 +2,12 @@ import { FoundTableActionDTO } from '../../table-action-rules-module/application import { TableActionEntity } from '../table-action.entity.js'; export function buildFoundTableActionDTO(tableAction: TableActionEntity): FoundTableActionDTO { - return { - id: tableAction.id, - emails: tableAction.emails, - method: tableAction.method, - url: tableAction.url, - slack_url: tableAction.slack_url, - created_at: tableAction.created_at, - }; + return { + id: tableAction.id, + emails: tableAction.emails, + method: tableAction.method, + url: tableAction.url, + slack_url: tableAction.slack_url, + created_at: tableAction.created_at, + }; } diff --git a/backend/src/entities/table-actions/table-actions-module/utils/build-table-action-with-rule.util.ts b/backend/src/entities/table-actions/table-actions-module/utils/build-table-action-with-rule.util.ts index 9f30cd8e1..779fe26aa 100644 --- a/backend/src/entities/table-actions/table-actions-module/utils/build-table-action-with-rule.util.ts +++ b/backend/src/entities/table-actions/table-actions-module/utils/build-table-action-with-rule.util.ts @@ -3,15 +3,15 @@ import { CreateTableActionData } from '../../table-action-rules-module/applicati import { TableActionEntity } from '../table-action.entity.js'; export function buildTableActionWithRule( - tableActionData: CreateTableActionData, - actionRule: ActionRulesEntity, + tableActionData: CreateTableActionData, + actionRule: ActionRulesEntity, ): TableActionEntity { - const { action_emails, action_method, action_url, action_slack_url } = tableActionData; - const newTableAction = new TableActionEntity(); - newTableAction.action_rule = actionRule; - newTableAction.emails = action_emails; - newTableAction.method = action_method; - newTableAction.url = action_url; - newTableAction.slack_url = action_slack_url; - return newTableAction; + const { action_emails, action_method, action_url, action_slack_url } = tableActionData; + const newTableAction = new TableActionEntity(); + newTableAction.action_rule = actionRule; + newTableAction.emails = action_emails; + newTableAction.method = action_method; + newTableAction.url = action_url; + newTableAction.slack_url = action_slack_url; + return newTableAction; } diff --git a/backend/src/entities/table-categories/data-sctructures/create-or-update-table-categories.ds.ts b/backend/src/entities/table-categories/data-sctructures/create-or-update-table-categories.ds.ts index 6c0ac7a1e..24f105372 100644 --- a/backend/src/entities/table-categories/data-sctructures/create-or-update-table-categories.ds.ts +++ b/backend/src/entities/table-categories/data-sctructures/create-or-update-table-categories.ds.ts @@ -1,12 +1,12 @@ export class TableCategoryDS { - category_name: string; - category_color: string; - category_id: string; - tables: Array; + category_name: string; + category_color: string; + category_id: string; + tables: Array; } export class CreateOrUpdateTableCategoriesDS { - connectionId: string; - master_password: string; - table_categories: Array; + connectionId: string; + master_password: string; + table_categories: Array; } diff --git a/backend/src/entities/table-categories/dto/create-table-category.dto.ts b/backend/src/entities/table-categories/dto/create-table-category.dto.ts index 00aaa6e3f..b79564f72 100644 --- a/backend/src/entities/table-categories/dto/create-table-category.dto.ts +++ b/backend/src/entities/table-categories/dto/create-table-category.dto.ts @@ -2,31 +2,31 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsArray, IsNotEmpty, IsOptional, IsString, MaxLength, MinLength } from 'class-validator'; export class CreateTableCategoryDto { - @ApiProperty({ type: String, maxLength: 255, example: 'Category 1' }) - @IsString() - @IsNotEmpty() - @MinLength(1) - @MaxLength(255) - category_name: string; + @ApiProperty({ type: String, maxLength: 255, example: 'Category 1' }) + @IsString() + @IsNotEmpty() + @MinLength(1) + @MaxLength(255) + category_name: string; - @ApiProperty({ type: String, maxLength: 255, example: '#FF5733' }) - @IsOptional() - @IsString() - @IsNotEmpty() - @MinLength(1) - @MaxLength(255) - category_color: string; + @ApiProperty({ type: String, maxLength: 255, example: '#FF5733' }) + @IsOptional() + @IsString() + @IsNotEmpty() + @MinLength(1) + @MaxLength(255) + category_color: string; - @ApiProperty({ type: String, example: ['table1', 'table2'], isArray: true }) - @IsNotEmpty() - @IsArray() - @IsString({ each: true }) - tables: string[]; + @ApiProperty({ type: String, example: ['table1', 'table2'], isArray: true }) + @IsNotEmpty() + @IsArray() + @IsString({ each: true }) + tables: string[]; - @ApiProperty({ type: String, maxLength: 255, example: 'cat-001' }) - @IsString() - @IsNotEmpty() - @MinLength(1) - @MaxLength(255) - category_id: string; + @ApiProperty({ type: String, maxLength: 255, example: 'cat-001' }) + @IsString() + @IsNotEmpty() + @MinLength(1) + @MaxLength(255) + category_id: string; } diff --git a/backend/src/entities/table-categories/dto/found-table-category.ro.ts b/backend/src/entities/table-categories/dto/found-table-category.ro.ts index 4ede716a2..75980bb48 100644 --- a/backend/src/entities/table-categories/dto/found-table-category.ro.ts +++ b/backend/src/entities/table-categories/dto/found-table-category.ro.ts @@ -1,15 +1,15 @@ import { ApiProperty } from '@nestjs/swagger'; export class FoundTableCategoryRo { - @ApiProperty({ type: String }) - category_id: string; + @ApiProperty({ type: String }) + category_id: string; - @ApiProperty({ type: String }) - category_name: string; + @ApiProperty({ type: String }) + category_name: string; - @ApiProperty({ type: String }) - category_color: string; + @ApiProperty({ type: String }) + category_color: string; - @ApiProperty({ isArray: true, type: String }) - tables: Array; + @ApiProperty({ isArray: true, type: String }) + tables: Array; } diff --git a/backend/src/entities/table-categories/repository/table-categories-repository.extension.ts b/backend/src/entities/table-categories/repository/table-categories-repository.extension.ts index 716b5d25c..f2ee5687e 100644 --- a/backend/src/entities/table-categories/repository/table-categories-repository.extension.ts +++ b/backend/src/entities/table-categories/repository/table-categories-repository.extension.ts @@ -2,11 +2,11 @@ import { TableCategoriesEntity } from '../table-categories.entity.js'; import { ITableCategoriesCustomRepository } from './table-categories-repository.interface.js'; export const tableCategoriesCustomRepositoryExtension: ITableCategoriesCustomRepository = { - async findTableCategoriesForConnection(connectionId: string): Promise> { - return this.createQueryBuilder('table_categories') - .leftJoin('table_categories.connection_properties', 'connection_properties') - .leftJoin('connection_properties.connection', 'connection') - .where('connection.id = :connectionId', { connectionId: connectionId }) - .getMany(); - }, + async findTableCategoriesForConnection(connectionId: string): Promise> { + return this.createQueryBuilder('table_categories') + .leftJoin('table_categories.connection_properties', 'connection_properties') + .leftJoin('connection_properties.connection', 'connection') + .where('connection.id = :connectionId', { connectionId: connectionId }) + .getMany(); + }, }; diff --git a/backend/src/entities/table-categories/repository/table-categories-repository.interface.ts b/backend/src/entities/table-categories/repository/table-categories-repository.interface.ts index 24f35ce9f..c5c605e89 100644 --- a/backend/src/entities/table-categories/repository/table-categories-repository.interface.ts +++ b/backend/src/entities/table-categories/repository/table-categories-repository.interface.ts @@ -1,5 +1,5 @@ import { TableCategoriesEntity } from '../table-categories.entity.js'; export interface ITableCategoriesCustomRepository { - findTableCategoriesForConnection(connectionId: string): Promise>; + findTableCategoriesForConnection(connectionId: string): Promise>; } diff --git a/backend/src/entities/table-categories/table-categories.controller.ts b/backend/src/entities/table-categories/table-categories.controller.ts index 9dd488128..46636f145 100644 --- a/backend/src/entities/table-categories/table-categories.controller.ts +++ b/backend/src/entities/table-categories/table-categories.controller.ts @@ -3,6 +3,7 @@ import { ApiBearerAuth, ApiBody, ApiOperation, ApiParam, ApiResponse, ApiTags } import { UseCaseType } from '../../common/data-injection.tokens.js'; import { MasterPassword } from '../../decorators/master-password.decorator.js'; import { SlugUuid } from '../../decorators/slug-uuid.decorator.js'; +import { Timeout } from '../../decorators/timeout.decorator.js'; import { InTransactionEnum } from '../../enums/in-transaction.enum.js'; import { ConnectionEditGuard } from '../../guards/connection-edit.guard.js'; import { TablesReceiveGuard } from '../../guards/tables-receive.guard.js'; @@ -11,7 +12,6 @@ import { CreateOrUpdateTableCategoriesDS } from './data-sctructures/create-or-up import { CreateTableCategoryDto } from './dto/create-table-category.dto.js'; import { FoundTableCategoryRo } from './dto/found-table-category.ro.js'; import { ICreateTableCategories, IFindTableCategories } from './use-cases/table-categories-use-cases.interface.js'; -import { Timeout } from '../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/table-categories/table-categories.entity.ts b/backend/src/entities/table-categories/table-categories.entity.ts index 66eefbfc5..8a60fbe08 100644 --- a/backend/src/entities/table-categories/table-categories.entity.ts +++ b/backend/src/entities/table-categories/table-categories.entity.ts @@ -3,27 +3,31 @@ import { ConnectionPropertiesEntity } from '../connection-properties/connection- @Entity('table_categories') export class TableCategoriesEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ type: 'varchar', length: 255 }) - category_name: string; + @Column({ type: 'varchar', length: 255 }) + category_name: string; - @Column({ type: 'varchar', length: 255, nullable: true, default: null }) - category_id: string; + @Column({ type: 'varchar', length: 255, nullable: true, default: null }) + category_id: string; - @Column({ type: 'varchar', length: 255, default: null, nullable: true }) - category_color: string; + @Column({ type: 'varchar', length: 255, default: null, nullable: true }) + category_color: string; - @Column('varchar', { array: true, default: null }) - tables: string[]; + @Column('varchar', { array: true, default: null }) + tables: string[]; - @ManyToOne(() => ConnectionPropertiesEntity, (connection_properties) => connection_properties.table_categories, { - onDelete: 'CASCADE', - }) - @JoinColumn({ name: 'connection_properties_id' }) - connection_properties: Relation; + @ManyToOne( + () => ConnectionPropertiesEntity, + (connection_properties) => connection_properties.table_categories, + { + onDelete: 'CASCADE', + }, + ) + @JoinColumn({ name: 'connection_properties_id' }) + connection_properties: Relation; - @Column() - connection_properties_id: string; + @Column() + connection_properties_id: string; } diff --git a/backend/src/entities/table-categories/table-categories.module.ts b/backend/src/entities/table-categories/table-categories.module.ts index d979a927d..352081e41 100644 --- a/backend/src/entities/table-categories/table-categories.module.ts +++ b/backend/src/entities/table-categories/table-categories.module.ts @@ -1,39 +1,39 @@ +import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthMiddleware } from '../../authorization/auth.middleware.js'; import { GlobalDatabaseContext } from '../../common/application/global-database-context.js'; import { BaseType, UseCaseType } from '../../common/data-injection.tokens.js'; -import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'; -import { AuthMiddleware } from '../../authorization/auth.middleware.js'; +import { LogOutEntity } from '../log-out/log-out.entity.js'; +import { UserEntity } from '../user/user.entity.js'; import { TableCategoriesController } from './table-categories.controller.js'; -import { FindTableCategoriesUseCase } from './use-cases/find-table-categories.use.case.js'; import { CreateOrUpdateTableCategoriesUseCase } from './use-cases/create-or-update-table-categories.use.case.js'; -import { UserEntity } from '../user/user.entity.js'; -import { LogOutEntity } from '../log-out/log-out.entity.js'; +import { FindTableCategoriesUseCase } from './use-cases/find-table-categories.use.case.js'; @Module({ - imports: [TypeOrmModule.forFeature([UserEntity, LogOutEntity])], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.FIND_TABLE_CATEGORIES, - useClass: FindTableCategoriesUseCase, - }, - { - provide: UseCaseType.CREATE_UPDATE_TABLE_CATEGORIES, - useClass: CreateOrUpdateTableCategoriesUseCase, - }, - ], - controllers: [TableCategoriesController], + imports: [TypeOrmModule.forFeature([UserEntity, LogOutEntity])], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.FIND_TABLE_CATEGORIES, + useClass: FindTableCategoriesUseCase, + }, + { + provide: UseCaseType.CREATE_UPDATE_TABLE_CATEGORIES, + useClass: CreateOrUpdateTableCategoriesUseCase, + }, + ], + controllers: [TableCategoriesController], }) export class TableCategoriesModule { - public configure(consumer: MiddlewareConsumer): any { - consumer - .apply(AuthMiddleware) - .forRoutes( - { path: '/table-categories/:connectionId/', method: RequestMethod.GET }, - { path: '/table-categories/:connectionId/', method: RequestMethod.PUT }, - ); - } + public configure(consumer: MiddlewareConsumer): any { + consumer + .apply(AuthMiddleware) + .forRoutes( + { path: '/table-categories/:connectionId/', method: RequestMethod.GET }, + { path: '/table-categories/:connectionId/', method: RequestMethod.PUT }, + ); + } } diff --git a/backend/src/entities/table-categories/use-cases/create-or-update-table-categories.use.case.ts b/backend/src/entities/table-categories/use-cases/create-or-update-table-categories.use.case.ts index e4eaad44a..ddd89f2e1 100644 --- a/backend/src/entities/table-categories/use-cases/create-or-update-table-categories.use.case.ts +++ b/backend/src/entities/table-categories/use-cases/create-or-update-table-categories.use.case.ts @@ -2,60 +2,60 @@ import { Inject, Injectable } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import { ICreateTableCategories } from './table-categories-use-cases.interface.js'; -import { FoundTableCategoryRo } from '../dto/found-table-category.ro.js'; import { CreateOrUpdateTableCategoriesDS } from '../data-sctructures/create-or-update-table-categories.ds.js'; -import { validateTableCategories } from '../utils/validate-table-categories.util.js'; +import { FoundTableCategoryRo } from '../dto/found-table-category.ro.js'; import { buildFoundTableCategoryRo } from '../utils/build-found-table-category.ro.js'; +import { validateTableCategories } from '../utils/validate-table-categories.util.js'; +import { ICreateTableCategories } from './table-categories-use-cases.interface.js'; @Injectable() export class CreateOrUpdateTableCategoriesUseCase - extends AbstractUseCase> - implements ICreateTableCategories + extends AbstractUseCase> + implements ICreateTableCategories { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } - - protected async implementation(inputData: CreateOrUpdateTableCategoriesDS): Promise> { - const { connectionId, master_password, table_categories } = inputData; - const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( - connectionId, - master_password, - ); - - await validateTableCategories(table_categories, foundConnection); - - const foundTableCategories = - await this._dbContext.tableCategoriesRepository.findTableCategoriesForConnection(connectionId); - - if (foundTableCategories.length) { - await this._dbContext.tableCategoriesRepository.remove(foundTableCategories); - } - - let connectionProperties = - await this._dbContext.connectionPropertiesRepository.findConnectionProperties(connectionId); - - if (!connectionProperties) { - const newConnectionProperties = this._dbContext.connectionPropertiesRepository.create({}); - newConnectionProperties.connection = foundConnection; - connectionProperties = await this._dbContext.connectionPropertiesRepository.save(newConnectionProperties); - } - - const createdCategories = table_categories.map((category) => { - const newCategory = this._dbContext.tableCategoriesRepository.create({ - category_name: category.category_name, - tables: category.tables, - category_color: category.category_color, - category_id: category.category_id, - }); - newCategory.connection_properties = connectionProperties; - return newCategory; - }); - const savedCategories = await this._dbContext.tableCategoriesRepository.save(createdCategories); - return savedCategories.map((category) => buildFoundTableCategoryRo(category)); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } + + protected async implementation(inputData: CreateOrUpdateTableCategoriesDS): Promise> { + const { connectionId, master_password, table_categories } = inputData; + const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( + connectionId, + master_password, + ); + + await validateTableCategories(table_categories, foundConnection); + + const foundTableCategories = + await this._dbContext.tableCategoriesRepository.findTableCategoriesForConnection(connectionId); + + if (foundTableCategories.length) { + await this._dbContext.tableCategoriesRepository.remove(foundTableCategories); + } + + let connectionProperties = + await this._dbContext.connectionPropertiesRepository.findConnectionProperties(connectionId); + + if (!connectionProperties) { + const newConnectionProperties = this._dbContext.connectionPropertiesRepository.create({}); + newConnectionProperties.connection = foundConnection; + connectionProperties = await this._dbContext.connectionPropertiesRepository.save(newConnectionProperties); + } + + const createdCategories = table_categories.map((category) => { + const newCategory = this._dbContext.tableCategoriesRepository.create({ + category_name: category.category_name, + tables: category.tables, + category_color: category.category_color, + category_id: category.category_id, + }); + newCategory.connection_properties = connectionProperties; + return newCategory; + }); + const savedCategories = await this._dbContext.tableCategoriesRepository.save(createdCategories); + return savedCategories.map((category) => buildFoundTableCategoryRo(category)); + } } diff --git a/backend/src/entities/table-categories/use-cases/find-table-categories.use.case.ts b/backend/src/entities/table-categories/use-cases/find-table-categories.use.case.ts index 2f9a2a27f..ef140a846 100644 --- a/backend/src/entities/table-categories/use-cases/find-table-categories.use.case.ts +++ b/backend/src/entities/table-categories/use-cases/find-table-categories.use.case.ts @@ -1,27 +1,27 @@ import { Inject, Injectable } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { IFindTableCategories } from './table-categories-use-cases.interface.js'; -import { BaseType } from '../../../common/data-injection.tokens.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; +import { BaseType } from '../../../common/data-injection.tokens.js'; import { FoundTableCategoryRo } from '../dto/found-table-category.ro.js'; import { buildFoundTableCategoryRo } from '../utils/build-found-table-category.ro.js'; +import { IFindTableCategories } from './table-categories-use-cases.interface.js'; @Injectable() export class FindTableCategoriesUseCase - extends AbstractUseCase> - implements IFindTableCategories + extends AbstractUseCase> + implements IFindTableCategories { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(connectionId: string): Promise> { - const foundTableCategories = - await this._dbContext.tableCategoriesRepository.findTableCategoriesForConnection(connectionId); + protected async implementation(connectionId: string): Promise> { + const foundTableCategories = + await this._dbContext.tableCategoriesRepository.findTableCategoriesForConnection(connectionId); - return foundTableCategories.map((category) => buildFoundTableCategoryRo(category)); - } + return foundTableCategories.map((category) => buildFoundTableCategoryRo(category)); + } } diff --git a/backend/src/entities/table-categories/use-cases/table-categories-use-cases.interface.ts b/backend/src/entities/table-categories/use-cases/table-categories-use-cases.interface.ts index 5f2856eb8..69238c63c 100644 --- a/backend/src/entities/table-categories/use-cases/table-categories-use-cases.interface.ts +++ b/backend/src/entities/table-categories/use-cases/table-categories-use-cases.interface.ts @@ -3,12 +3,12 @@ import { CreateOrUpdateTableCategoriesDS } from '../data-sctructures/create-or-u import { FoundTableCategoryRo } from '../dto/found-table-category.ro.js'; export interface ICreateTableCategories { - execute( - inputData: CreateOrUpdateTableCategoriesDS, - inTransaction: InTransactionEnum, - ): Promise>; + execute( + inputData: CreateOrUpdateTableCategoriesDS, + inTransaction: InTransactionEnum, + ): Promise>; } export interface IFindTableCategories { - execute(connectionId: string): Promise>; + execute(connectionId: string): Promise>; } diff --git a/backend/src/entities/table-categories/utils/build-found-table-category.ro.ts b/backend/src/entities/table-categories/utils/build-found-table-category.ro.ts index 2d916fb96..5770d3cc7 100644 --- a/backend/src/entities/table-categories/utils/build-found-table-category.ro.ts +++ b/backend/src/entities/table-categories/utils/build-found-table-category.ro.ts @@ -2,10 +2,10 @@ import { FoundTableCategoryRo } from '../dto/found-table-category.ro.js'; import { TableCategoriesEntity } from '../table-categories.entity.js'; export function buildFoundTableCategoryRo(tableCategory: TableCategoriesEntity): FoundTableCategoryRo { - return { - category_id: tableCategory.category_id, - category_name: tableCategory.category_name, - category_color: tableCategory.category_color, - tables: tableCategory.tables, - }; + return { + category_id: tableCategory.category_id, + category_name: tableCategory.category_name, + category_color: tableCategory.category_color, + tables: tableCategory.tables, + }; } diff --git a/backend/src/entities/table-categories/utils/validate-table-categories.util.ts b/backend/src/entities/table-categories/utils/validate-table-categories.util.ts index 506ca4f15..a54a68cfe 100644 --- a/backend/src/entities/table-categories/utils/validate-table-categories.util.ts +++ b/backend/src/entities/table-categories/utils/validate-table-categories.util.ts @@ -1,35 +1,35 @@ +import { BadRequestException } from '@nestjs/common'; import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import { ConnectionEntity } from '../../connection/connection.entity.js'; import { TableCategoryDS } from '../data-sctructures/create-or-update-table-categories.ds.js'; -import { BadRequestException } from '@nestjs/common'; export async function validateTableCategories( - tableCategoriesData: Array, - connection: ConnectionEntity, + tableCategoriesData: Array, + connection: ConnectionEntity, ): Promise { - tableCategoriesData.forEach((category) => { - if (!category.category_name || category.category_name.trim() === '') { - throw new BadRequestException('Table category name cannot be empty.'); - } - if (!Array.isArray(category.tables)) { - throw new BadRequestException('Tables must be an array of table names.'); - } - if (category.category_id === undefined || category.category_id.trim() === '') { - throw new BadRequestException('Table category ID cannot be empty.'); - } - }); - const dao = getDataAccessObject(connection); - const tablesInConnection = (await dao.getTablesFromDB()).map((table) => table.tableName); - const tables = tableCategoriesData.flatMap((category) => category.tables); - const uniqueTables = Array.from(new Set(tables)); - const errors = []; - for (const table of uniqueTables) { - if (!tablesInConnection.includes(table)) { - errors.push(`Table with name ${table} does not exist in the connection.`); - } - } - if (errors.length > 0) { - throw new BadRequestException('Table categories validation failed: ' + errors.join(', ')); - } - return true; + tableCategoriesData.forEach((category) => { + if (!category.category_name || category.category_name.trim() === '') { + throw new BadRequestException('Table category name cannot be empty.'); + } + if (!Array.isArray(category.tables)) { + throw new BadRequestException('Tables must be an array of table names.'); + } + if (category.category_id === undefined || category.category_id.trim() === '') { + throw new BadRequestException('Table category ID cannot be empty.'); + } + }); + const dao = getDataAccessObject(connection); + const tablesInConnection = (await dao.getTablesFromDB()).map((table) => table.tableName); + const tables = tableCategoriesData.flatMap((category) => category.tables); + const uniqueTables = Array.from(new Set(tables)); + const errors = []; + for (const table of uniqueTables) { + if (!tablesInConnection.includes(table)) { + errors.push(`Table with name ${table} does not exist in the connection.`); + } + } + if (errors.length > 0) { + throw new BadRequestException('Table categories validation failed: ' + errors.join(', ')); + } + return true; } diff --git a/backend/src/entities/table-field-info/table-field-info.entity.ts b/backend/src/entities/table-field-info/table-field-info.entity.ts index 6bba82ace..bf17850b9 100644 --- a/backend/src/entities/table-field-info/table-field-info.entity.ts +++ b/backend/src/entities/table-field-info/table-field-info.entity.ts @@ -3,31 +3,35 @@ import { TableInfoEntity } from '../table-info/table-info.entity.js'; @Entity('table_field_info') export class TableFieldInfoEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ default: null, type: 'boolean' }) - allow_null: boolean; + @Column({ default: null, type: 'boolean' }) + allow_null: boolean; - @Column({ default: null }) - character_maximum_length: string; + @Column({ default: null }) + character_maximum_length: string; - @Column({ default: null }) - column_default: string; + @Column({ default: null }) + column_default: string; - @Column({ default: null }) - column_name: string; + @Column({ default: null }) + column_name: string; - @Column({ default: null }) - data_type: string; + @Column({ default: null }) + data_type: string; - @Column({ default: null }) - data_type_params: string; + @Column({ default: null }) + data_type_params: string; - @Column({ default: null }) - udt_name: string; + @Column({ default: null }) + udt_name: string; - @ManyToOne(() => TableInfoEntity, (table_info) => table_info.table_fields_info, { onDelete: 'CASCADE' }) - @JoinColumn() - table_info: Relation; + @ManyToOne( + () => TableInfoEntity, + (table_info) => table_info.table_fields_info, + { onDelete: 'CASCADE' }, + ) + @JoinColumn() + table_info: Relation; } diff --git a/backend/src/entities/table-filters/application/data-structures/create-table-filters.ds.ts b/backend/src/entities/table-filters/application/data-structures/create-table-filters.ds.ts index cad61058d..4a8a1753b 100644 --- a/backend/src/entities/table-filters/application/data-structures/create-table-filters.ds.ts +++ b/backend/src/entities/table-filters/application/data-structures/create-table-filters.ds.ts @@ -1,14 +1,14 @@ import { FilterCriteriaEnum } from '../../../../enums/filter-criteria.enum.js'; export class DynamicTableFiltersDs { - column_name: string; - comparator: FilterCriteriaEnum; + column_name: string; + comparator: FilterCriteriaEnum; } export class CreateTableFilterDs { - table_name: string; - connection_id: string; - filters: Record; - masterPwd: string; - filter_name: string; - dynamic_filtered_column: DynamicTableFiltersDs | null; + table_name: string; + connection_id: string; + filters: Record; + masterPwd: string; + filter_name: string; + dynamic_filtered_column: DynamicTableFiltersDs | null; } diff --git a/backend/src/entities/table-filters/application/data-structures/find-table-filters.ds.ts b/backend/src/entities/table-filters/application/data-structures/find-table-filters.ds.ts index 2b053acda..d624fc601 100644 --- a/backend/src/entities/table-filters/application/data-structures/find-table-filters.ds.ts +++ b/backend/src/entities/table-filters/application/data-structures/find-table-filters.ds.ts @@ -1,9 +1,9 @@ export class FindTableFiltersDs { - table_name: string; - connection_id: string; + table_name: string; + connection_id: string; } export class FindTableFilterByIdDs { - filter_id: string; - connection_id: string; -} \ No newline at end of file + filter_id: string; + connection_id: string; +} diff --git a/backend/src/entities/table-filters/application/data-structures/update-table-filters.ds.ts b/backend/src/entities/table-filters/application/data-structures/update-table-filters.ds.ts index a26ace2f9..4108067c8 100644 --- a/backend/src/entities/table-filters/application/data-structures/update-table-filters.ds.ts +++ b/backend/src/entities/table-filters/application/data-structures/update-table-filters.ds.ts @@ -1,10 +1,10 @@ import { DynamicTableFiltersDs } from './create-table-filters.ds.js'; export class UpdateTableFilterDs { - filter_id: string; - connection_id: string; - filters: Record; - masterPwd: string; - filter_name: string; - dynamic_filtered_column: DynamicTableFiltersDs | null; + filter_id: string; + connection_id: string; + filters: Record; + masterPwd: string; + filter_name: string; + dynamic_filtered_column: DynamicTableFiltersDs | null; } diff --git a/backend/src/entities/table-filters/application/response-objects/create-table-filters.dto.ts b/backend/src/entities/table-filters/application/response-objects/create-table-filters.dto.ts index c7aae58e6..bc4d51754 100644 --- a/backend/src/entities/table-filters/application/response-objects/create-table-filters.dto.ts +++ b/backend/src/entities/table-filters/application/response-objects/create-table-filters.dto.ts @@ -3,64 +3,64 @@ import { IsObject, IsOptional, IsString, MaxLength, MinLength, ValidateNested } import { FilterCriteriaEnum } from '../../../../enums/filter-criteria.enum.js'; export class DynamicTableFilterDto { - @ApiProperty({ type: 'string' }) - @IsString() - @MinLength(1) - @MaxLength(255) - column_name: string; + @ApiProperty({ type: 'string' }) + @IsString() + @MinLength(1) + @MaxLength(255) + column_name: string; - @ApiProperty({ enum: FilterCriteriaEnum }) - comparator: FilterCriteriaEnum; + @ApiProperty({ enum: FilterCriteriaEnum }) + comparator: FilterCriteriaEnum; } export class CreateTableFilterDto { - @ApiProperty({ type: 'string' }) - @IsString() - @MinLength(1) - @MaxLength(255) - name: string; + @ApiProperty({ type: 'string' }) + @IsString() + @MinLength(1) + @MaxLength(255) + name: string; - @ApiProperty({ - type: 'object', - properties: { - id: { - type: 'object', - properties: { - eq: { type: 'number' }, - }, - }, - name: { - type: 'object', - properties: { - startswith: { type: 'string' }, - }, - }, - age: { - type: 'object', - properties: { - gt: { type: 'number' }, - lt: { type: 'number' }, - }, - }, - }, - example: { - id: { - eq: 1, - }, - name: { - startswith: 'A', - }, - age: { - gt: 18, - lt: 30, - }, - }, - }) - @IsObject() - filters: Record; + @ApiProperty({ + type: 'object', + properties: { + id: { + type: 'object', + properties: { + eq: { type: 'number' }, + }, + }, + name: { + type: 'object', + properties: { + startswith: { type: 'string' }, + }, + }, + age: { + type: 'object', + properties: { + gt: { type: 'number' }, + lt: { type: 'number' }, + }, + }, + }, + example: { + id: { + eq: 1, + }, + name: { + startswith: 'A', + }, + age: { + gt: 18, + lt: 30, + }, + }, + }) + @IsObject() + filters: Record; - @ApiProperty({ type: DynamicTableFilterDto, required: false }) - @IsOptional() - @ValidateNested() - dynamic_column: DynamicTableFilterDto; + @ApiProperty({ type: DynamicTableFilterDto, required: false }) + @IsOptional() + @ValidateNested() + dynamic_column: DynamicTableFilterDto; } diff --git a/backend/src/entities/table-filters/application/response-objects/created-table-filters.ro.ts b/backend/src/entities/table-filters/application/response-objects/created-table-filters.ro.ts index 4f387c8bb..66d1c8e3c 100644 --- a/backend/src/entities/table-filters/application/response-objects/created-table-filters.ro.ts +++ b/backend/src/entities/table-filters/application/response-objects/created-table-filters.ro.ts @@ -2,15 +2,15 @@ import { ApiProperty } from '@nestjs/swagger'; import { CreateTableFilterDto } from './create-table-filters.dto.js'; export class CreatedTableFilterRO extends CreateTableFilterDto { - @ApiProperty({ type: 'string' }) - id: string; + @ApiProperty({ type: 'string' }) + id: string; - @ApiProperty({ type: 'string' }) - table_name: string; + @ApiProperty({ type: 'string' }) + table_name: string; - @ApiProperty({ type: Date }) - createdAt: Date; + @ApiProperty({ type: Date }) + createdAt: Date; - @ApiProperty({ type: Date }) - updatedAt: Date; + @ApiProperty({ type: Date }) + updatedAt: Date; } diff --git a/backend/src/entities/table-filters/repository/table-filters-custom-repository-extension.ts b/backend/src/entities/table-filters/repository/table-filters-custom-repository-extension.ts index 977ff7ee6..fc9fc5cf1 100644 --- a/backend/src/entities/table-filters/repository/table-filters-custom-repository-extension.ts +++ b/backend/src/entities/table-filters/repository/table-filters-custom-repository-extension.ts @@ -2,25 +2,22 @@ import { TableFiltersEntity } from '../table-filters.entity.js'; import { ITableFiltersCustomRepository } from './table-filters-custom-repository.interface.js'; export const tableFiltersCustomRepositoryExtension: ITableFiltersCustomRepository = { - async findTableFiltersForTableInConnection( - tableName: string, - connectionId: string, - ): Promise> { - const qb = this.createQueryBuilder('table_filters') - .leftJoin('table_filters.connection', 'connection') - .where('table_filters.table_name = :tableName', { tableName: tableName }) - .andWhere('connection.id = :connectionId', { connectionId: connectionId }); - return await qb.getMany(); - }, + async findTableFiltersForTableInConnection( + tableName: string, + connectionId: string, + ): Promise> { + const qb = this.createQueryBuilder('table_filters') + .leftJoin('table_filters.connection', 'connection') + .where('table_filters.table_name = :tableName', { tableName: tableName }) + .andWhere('connection.id = :connectionId', { connectionId: connectionId }); + return await qb.getMany(); + }, - async findTableFiltersByIdAndConnectionId( - filterId: string, - connectionId: string, - ): Promise { - const qb = this.createQueryBuilder('table_filters') - .leftJoin('table_filters.connection', 'connection') - .where('table_filters.id = :filterId', { filterId: filterId }) - .andWhere('connection.id = :connectionId', { connectionId: connectionId }); - return await qb.getOne(); - }, + async findTableFiltersByIdAndConnectionId(filterId: string, connectionId: string): Promise { + const qb = this.createQueryBuilder('table_filters') + .leftJoin('table_filters.connection', 'connection') + .where('table_filters.id = :filterId', { filterId: filterId }) + .andWhere('connection.id = :connectionId', { connectionId: connectionId }); + return await qb.getOne(); + }, }; diff --git a/backend/src/entities/table-filters/repository/table-filters-custom-repository.interface.ts b/backend/src/entities/table-filters/repository/table-filters-custom-repository.interface.ts index 9eeb47929..dae394b27 100644 --- a/backend/src/entities/table-filters/repository/table-filters-custom-repository.interface.ts +++ b/backend/src/entities/table-filters/repository/table-filters-custom-repository.interface.ts @@ -1,7 +1,7 @@ import { TableFiltersEntity } from '../table-filters.entity.js'; export interface ITableFiltersCustomRepository { - findTableFiltersForTableInConnection(tableName: string, connectionId: string): Promise>; + findTableFiltersForTableInConnection(tableName: string, connectionId: string): Promise>; - findTableFiltersByIdAndConnectionId(filterId: string, connectionId: string): Promise; + findTableFiltersByIdAndConnectionId(filterId: string, connectionId: string): Promise; } diff --git a/backend/src/entities/table-filters/table-filters.controller.ts b/backend/src/entities/table-filters/table-filters.controller.ts index 46d112ff3..0f937d527 100644 --- a/backend/src/entities/table-filters/table-filters.controller.ts +++ b/backend/src/entities/table-filters/table-filters.controller.ts @@ -16,14 +16,17 @@ import { UseCaseType } from '../../common/data-injection.tokens.js'; import { MasterPassword } from '../../decorators/master-password.decorator.js'; import { QueryTableName } from '../../decorators/query-table-name.decorator.js'; import { SlugUuid } from '../../decorators/slug-uuid.decorator.js'; +import { Timeout } from '../../decorators/timeout.decorator.js'; import { InTransactionEnum } from '../../enums/in-transaction.enum.js'; import { Messages } from '../../exceptions/text/messages.js'; import { ConnectionEditGuard } from '../../guards/connection-edit.guard.js'; import { ConnectionReadGuard } from '../../guards/connection-read.guard.js'; +import { TableReadGuard } from '../../guards/table-read.guard.js'; import { SentryInterceptor } from '../../interceptors/index.js'; import { SuccessResponse } from '../../microservices/saas-microservice/data-structures/common-responce.ds.js'; import { CreateTableFilterDs } from './application/data-structures/create-table-filters.ds.js'; import { FindTableFilterByIdDs, FindTableFiltersDs } from './application/data-structures/find-table-filters.ds.js'; +import { UpdateTableFilterDs } from './application/data-structures/update-table-filters.ds.js'; import { CreateTableFilterDto } from './application/response-objects/create-table-filters.dto.js'; import { CreatedTableFilterRO } from './application/response-objects/created-table-filters.ro.js'; import { @@ -34,9 +37,6 @@ import { IFindTableFilters, IUpdateTableFilterById, } from './use-cases/table-filters-use-cases.interface.js'; -import { UpdateTableFilterDs } from './application/data-structures/update-table-filters.ds.js'; -import { TableReadGuard } from '../../guards/table-read.guard.js'; -import { Timeout } from '../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/table-filters/table-filters.entity.ts b/backend/src/entities/table-filters/table-filters.entity.ts index 74f96bad4..cc047ea50 100644 --- a/backend/src/entities/table-filters/table-filters.entity.ts +++ b/backend/src/entities/table-filters/table-filters.entity.ts @@ -1,64 +1,68 @@ import { - BeforeInsert, - BeforeUpdate, - Column, - Entity, - JoinColumn, - ManyToOne, - PrimaryGeneratedColumn, - Relation, + BeforeInsert, + BeforeUpdate, + Column, + Entity, + JoinColumn, + ManyToOne, + PrimaryGeneratedColumn, + Relation, } from 'typeorm'; -import { ConnectionEntity } from '../connection/connection.entity.js'; import { FilterCriteriaEnum } from '../../enums/filter-criteria.enum.js'; +import { ConnectionEntity } from '../connection/connection.entity.js'; @Entity('table_filters') export class TableFiltersEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ type: 'jsonb', nullable: true }) - filters: Record; + @Column({ type: 'jsonb', nullable: true }) + filters: Record; - @Column({ default: null }) - table_name: string; + @Column({ default: null }) + table_name: string; - @Column({ type: 'varchar', length: 255, nullable: true }) - name: string | null; + @Column({ type: 'varchar', length: 255, nullable: true }) + name: string | null; - @Column({ type: 'varchar', length: 255, nullable: true }) - dynamic_filter_column_name: string | null; + @Column({ type: 'varchar', length: 255, nullable: true }) + dynamic_filter_column_name: string | null; - @Column('enum', { - nullable: true, - enum: FilterCriteriaEnum, - default: null, - }) - dynamic_filter_comparator: FilterCriteriaEnum | null; + @Column('enum', { + nullable: true, + enum: FilterCriteriaEnum, + default: null, + }) + dynamic_filter_comparator: FilterCriteriaEnum | null; - @ManyToOne((_) => ConnectionEntity, (connection) => connection.table_filters, { - onDelete: 'CASCADE', - }) - @JoinColumn({ name: 'connectionId' }) - connection: Relation; + @ManyToOne( + (_) => ConnectionEntity, + (connection) => connection.table_filters, + { + onDelete: 'CASCADE', + }, + ) + @JoinColumn({ name: 'connectionId' }) + connection: Relation; - @Column() - connectionId: string; + @Column() + connectionId: string; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - createdAt: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + createdAt: Date; - @Column({ type: 'timestamp', default: null }) - updatedAt: Date; + @Column({ type: 'timestamp', default: null }) + updatedAt: Date; - @BeforeInsert() - setDefaultName(): void { - if (!this.name) { - this.name = 'New filter'; - } - } + @BeforeInsert() + setDefaultName(): void { + if (!this.name) { + this.name = 'New filter'; + } + } - @BeforeUpdate() - updateTimestamp(): void { - this.updatedAt = new Date(); - } + @BeforeUpdate() + updateTimestamp(): void { + this.updatedAt = new Date(); + } } diff --git a/backend/src/entities/table-filters/table-filters.module.ts b/backend/src/entities/table-filters/table-filters.module.ts index 05b6669aa..7deb4699e 100644 --- a/backend/src/entities/table-filters/table-filters.module.ts +++ b/backend/src/entities/table-filters/table-filters.module.ts @@ -3,62 +3,62 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { AuthMiddleware } from '../../authorization/auth.middleware.js'; import { GlobalDatabaseContext } from '../../common/application/global-database-context.js'; import { BaseType, UseCaseType } from '../../common/data-injection.tokens.js'; +import { LogOutEntity } from '../log-out/log-out.entity.js'; +import { UserEntity } from '../user/user.entity.js'; import { TableFiltersController } from './table-filters.controller.js'; import { TableFiltersEntity } from './table-filters.entity.js'; import { CreateTableFiltersUseCase } from './use-cases/create-table-filters.use.case.js'; -import { UserEntity } from '../user/user.entity.js'; -import { LogOutEntity } from '../log-out/log-out.entity.js'; -import { FindTableFiltersUseCase } from './use-cases/find-table-filters.use.case.js'; +import { DeleteTableFilterByIdUseCase } from './use-cases/delete-table-filter-by-id.use.case.js'; import { DeleteTableFiltersUseCase } from './use-cases/delete-table-filters.use.case.js'; import { FindTableFilterByIdUseCase } from './use-cases/find-filter-by-id-use.case.js'; -import { DeleteTableFilterByIdUseCase } from './use-cases/delete-table-filter-by-id.use.case.js'; +import { FindTableFiltersUseCase } from './use-cases/find-table-filters.use.case.js'; import { UpdateTableFiltersUseCase } from './use-cases/update-table-filters.use.case.js'; @Module({ - imports: [TypeOrmModule.forFeature([TableFiltersEntity, UserEntity, LogOutEntity])], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.CREATE_TABLE_FILTERS, - useClass: CreateTableFiltersUseCase, - }, - { - provide: UseCaseType.FIND_TABLE_FILTERS, - useClass: FindTableFiltersUseCase, - }, - { - provide: UseCaseType.DELETE_TABLE_FILTERS, - useClass: DeleteTableFiltersUseCase, - }, - { - provide: UseCaseType.FIND_TABLE_FILTER_BY_ID, - useClass: FindTableFilterByIdUseCase, - }, - { - provide: UseCaseType.DELETE_TABLE_FILTER_BY_ID, - useClass: DeleteTableFilterByIdUseCase, - }, - { - provide: UseCaseType.UPDATE_TABLE_FILTER_BY_ID, - useClass: UpdateTableFiltersUseCase, - }, - ], - controllers: [TableFiltersController], + imports: [TypeOrmModule.forFeature([TableFiltersEntity, UserEntity, LogOutEntity])], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.CREATE_TABLE_FILTERS, + useClass: CreateTableFiltersUseCase, + }, + { + provide: UseCaseType.FIND_TABLE_FILTERS, + useClass: FindTableFiltersUseCase, + }, + { + provide: UseCaseType.DELETE_TABLE_FILTERS, + useClass: DeleteTableFiltersUseCase, + }, + { + provide: UseCaseType.FIND_TABLE_FILTER_BY_ID, + useClass: FindTableFilterByIdUseCase, + }, + { + provide: UseCaseType.DELETE_TABLE_FILTER_BY_ID, + useClass: DeleteTableFilterByIdUseCase, + }, + { + provide: UseCaseType.UPDATE_TABLE_FILTER_BY_ID, + useClass: UpdateTableFiltersUseCase, + }, + ], + controllers: [TableFiltersController], }) export class TableFiltersModule { - public configure(consumer: MiddlewareConsumer): any { - consumer - .apply(AuthMiddleware) - .forRoutes( - { path: '/table-filters/:connectionId', method: RequestMethod.POST }, - { path: '/table-filters/:connectionId/all', method: RequestMethod.GET }, - { path: '/table-filters/:connectionId/:filterId', method: RequestMethod.GET }, - { path: '/table-filters/:connectionId/all', method: RequestMethod.DELETE }, - { path: '/table-filters/:connectionId/:filterId', method: RequestMethod.DELETE }, - { path: '/table-filters/:connectionId/:filterId', method: RequestMethod.PUT }, - ); - } + public configure(consumer: MiddlewareConsumer): any { + consumer + .apply(AuthMiddleware) + .forRoutes( + { path: '/table-filters/:connectionId', method: RequestMethod.POST }, + { path: '/table-filters/:connectionId/all', method: RequestMethod.GET }, + { path: '/table-filters/:connectionId/:filterId', method: RequestMethod.GET }, + { path: '/table-filters/:connectionId/all', method: RequestMethod.DELETE }, + { path: '/table-filters/:connectionId/:filterId', method: RequestMethod.DELETE }, + { path: '/table-filters/:connectionId/:filterId', method: RequestMethod.PUT }, + ); + } } diff --git a/backend/src/entities/table-filters/use-cases/create-table-filters.use.case.ts b/backend/src/entities/table-filters/use-cases/create-table-filters.use.case.ts index 27cef7b43..b7a699b66 100644 --- a/backend/src/entities/table-filters/use-cases/create-table-filters.use.case.ts +++ b/backend/src/entities/table-filters/use-cases/create-table-filters.use.case.ts @@ -13,35 +13,35 @@ import { ICreateTableFilters } from './table-filters-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class CreateTableFiltersUseCase - extends AbstractUseCase - implements ICreateTableFilters + extends AbstractUseCase + implements ICreateTableFilters { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: CreateTableFilterDs): Promise { - const { connection_id, masterPwd } = inputData; + protected async implementation(inputData: CreateTableFilterDs): Promise { + const { connection_id, masterPwd } = inputData; - const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( - connection_id, - masterPwd, - ); - if (foundConnection.is_frozen) { - throw new NonAvailableInFreePlanException(Messages.CONNECTION_IS_FROZEN); - } + const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( + connection_id, + masterPwd, + ); + if (foundConnection.is_frozen) { + throw new NonAvailableInFreePlanException(Messages.CONNECTION_IS_FROZEN); + } - const errors = await validateFiltersData(inputData, foundConnection); - if (errors.length > 0) { - throw new BadRequestException(errors.join(',\n')); - } + const errors = await validateFiltersData(inputData, foundConnection); + if (errors.length > 0) { + throw new BadRequestException(errors.join(',\n')); + } - const newTableFilters = buildNewTableFiltersEntity(inputData); + const newTableFilters = buildNewTableFiltersEntity(inputData); - const savedTableFilters = await this._dbContext.tableFiltersRepository.save(newTableFilters); - return buildCreatedTableFilterRO(savedTableFilters); - } + const savedTableFilters = await this._dbContext.tableFiltersRepository.save(newTableFilters); + return buildCreatedTableFilterRO(savedTableFilters); + } } diff --git a/backend/src/entities/table-filters/use-cases/delete-table-filter-by-id.use.case.ts b/backend/src/entities/table-filters/use-cases/delete-table-filter-by-id.use.case.ts index 00cc690c9..29272b954 100644 --- a/backend/src/entities/table-filters/use-cases/delete-table-filter-by-id.use.case.ts +++ b/backend/src/entities/table-filters/use-cases/delete-table-filter-by-id.use.case.ts @@ -9,30 +9,30 @@ import { IDeleteTableFilterById } from './table-filters-use-cases.interface.js'; @Injectable() export class DeleteTableFilterByIdUseCase - extends AbstractUseCase - implements IDeleteTableFilterById + extends AbstractUseCase + implements IDeleteTableFilterById { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: FindTableFilterByIdDs): Promise { - const { filter_id, connection_id } = inputData; - const foundTableFilters = await this._dbContext.tableFiltersRepository.findTableFiltersByIdAndConnectionId( - filter_id, - connection_id, - ); + protected async implementation(inputData: FindTableFilterByIdDs): Promise { + const { filter_id, connection_id } = inputData; + const foundTableFilters = await this._dbContext.tableFiltersRepository.findTableFiltersByIdAndConnectionId( + filter_id, + connection_id, + ); - if (!foundTableFilters) { - throw new NotFoundException(Messages.TABLE_FILTERS_NOT_FOUND); - } + if (!foundTableFilters) { + throw new NotFoundException(Messages.TABLE_FILTERS_NOT_FOUND); + } - await this._dbContext.tableFiltersRepository.remove(foundTableFilters); - return { - success: true, - }; - } + await this._dbContext.tableFiltersRepository.remove(foundTableFilters); + return { + success: true, + }; + } } diff --git a/backend/src/entities/table-filters/use-cases/delete-table-filters.use.case.ts b/backend/src/entities/table-filters/use-cases/delete-table-filters.use.case.ts index d4f37b6bd..e04d4fa13 100644 --- a/backend/src/entities/table-filters/use-cases/delete-table-filters.use.case.ts +++ b/backend/src/entities/table-filters/use-cases/delete-table-filters.use.case.ts @@ -9,29 +9,29 @@ import { IDeleteTableFilters } from './table-filters-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class DeleteTableFiltersUseCase - extends AbstractUseCase - implements IDeleteTableFilters + extends AbstractUseCase + implements IDeleteTableFilters { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: FindTableFiltersDs): Promise { - const { table_name, connection_id } = inputData; - const foundTableFilters = await this._dbContext.tableFiltersRepository.findTableFiltersForTableInConnection( - table_name, - connection_id, - ); + protected async implementation(inputData: FindTableFiltersDs): Promise { + const { table_name, connection_id } = inputData; + const foundTableFilters = await this._dbContext.tableFiltersRepository.findTableFiltersForTableInConnection( + table_name, + connection_id, + ); - if (!foundTableFilters.length) { - throw new NotFoundException(Messages.TABLE_FILTERS_NOT_FOUND); - } - await this._dbContext.tableFiltersRepository.remove(foundTableFilters); - return { - success: true, - }; - } + if (!foundTableFilters.length) { + throw new NotFoundException(Messages.TABLE_FILTERS_NOT_FOUND); + } + await this._dbContext.tableFiltersRepository.remove(foundTableFilters); + return { + success: true, + }; + } } diff --git a/backend/src/entities/table-filters/use-cases/find-filter-by-id-use.case.ts b/backend/src/entities/table-filters/use-cases/find-filter-by-id-use.case.ts index 316b8cb3b..b1fe9d5e0 100644 --- a/backend/src/entities/table-filters/use-cases/find-filter-by-id-use.case.ts +++ b/backend/src/entities/table-filters/use-cases/find-filter-by-id-use.case.ts @@ -10,27 +10,27 @@ import { IFindTableFilterById } from './table-filters-use-cases.interface.js'; @Injectable() export class FindTableFilterByIdUseCase - extends AbstractUseCase - implements IFindTableFilterById + extends AbstractUseCase + implements IFindTableFilterById { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: FindTableFilterByIdDs): Promise { - const { filter_id, connection_id } = inputData; - const foundTableFilters = await this._dbContext.tableFiltersRepository.findTableFiltersByIdAndConnectionId( - filter_id, - connection_id, - ); + protected async implementation(inputData: FindTableFilterByIdDs): Promise { + const { filter_id, connection_id } = inputData; + const foundTableFilters = await this._dbContext.tableFiltersRepository.findTableFiltersByIdAndConnectionId( + filter_id, + connection_id, + ); - if (!foundTableFilters) { - throw new NotFoundException(Messages.TABLE_FILTERS_NOT_FOUND); - } + if (!foundTableFilters) { + throw new NotFoundException(Messages.TABLE_FILTERS_NOT_FOUND); + } - return buildCreatedTableFilterRO(foundTableFilters); - } + return buildCreatedTableFilterRO(foundTableFilters); + } } diff --git a/backend/src/entities/table-filters/use-cases/find-table-filters.use.case.ts b/backend/src/entities/table-filters/use-cases/find-table-filters.use.case.ts index eaceaa836..d437d920c 100644 --- a/backend/src/entities/table-filters/use-cases/find-table-filters.use.case.ts +++ b/backend/src/entities/table-filters/use-cases/find-table-filters.use.case.ts @@ -5,28 +5,28 @@ import { BaseType } from '../../../common/data-injection.tokens.js'; import { FindTableFiltersDs } from '../application/data-structures/find-table-filters.ds.js'; import { CreatedTableFilterRO } from '../application/response-objects/created-table-filters.ro.js'; -import { IFindTableFilters } from './table-filters-use-cases.interface.js'; import { buildCreatedTableFilterRO } from '../utils/build-created-table-filters-response-object.util.js'; +import { IFindTableFilters } from './table-filters-use-cases.interface.js'; @Injectable() export class FindTableFiltersUseCase - extends AbstractUseCase> - implements IFindTableFilters + extends AbstractUseCase> + implements IFindTableFilters { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: FindTableFiltersDs): Promise> { - const { table_name, connection_id } = inputData; - const foundTableFilters = await this._dbContext.tableFiltersRepository.findTableFiltersForTableInConnection( - table_name, - connection_id, - ); + protected async implementation(inputData: FindTableFiltersDs): Promise> { + const { table_name, connection_id } = inputData; + const foundTableFilters = await this._dbContext.tableFiltersRepository.findTableFiltersForTableInConnection( + table_name, + connection_id, + ); - return foundTableFilters.map((tableFilters) => buildCreatedTableFilterRO(tableFilters)); - } + return foundTableFilters.map((tableFilters) => buildCreatedTableFilterRO(tableFilters)); + } } diff --git a/backend/src/entities/table-filters/use-cases/table-filters-use-cases.interface.ts b/backend/src/entities/table-filters/use-cases/table-filters-use-cases.interface.ts index ca9663bb1..2b6227bac 100644 --- a/backend/src/entities/table-filters/use-cases/table-filters-use-cases.interface.ts +++ b/backend/src/entities/table-filters/use-cases/table-filters-use-cases.interface.ts @@ -6,25 +6,25 @@ import { UpdateTableFilterDs } from '../application/data-structures/update-table import { CreatedTableFilterRO } from '../application/response-objects/created-table-filters.ro.js'; export interface ICreateTableFilters { - execute(inputData: CreateTableFilterDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: CreateTableFilterDs, inTransaction: InTransactionEnum): Promise; } export interface IFindTableFilters { - execute(inputData: FindTableFiltersDs, inTransaction: InTransactionEnum): Promise>; + execute(inputData: FindTableFiltersDs, inTransaction: InTransactionEnum): Promise>; } export interface IFindTableFilterById { - execute(inputData: FindTableFilterByIdDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: FindTableFilterByIdDs, inTransaction: InTransactionEnum): Promise; } export interface IDeleteTableFilters { - execute(inputData: FindTableFiltersDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: FindTableFiltersDs, inTransaction: InTransactionEnum): Promise; } export interface IDeleteTableFilterById { - execute(inputData: FindTableFilterByIdDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: FindTableFilterByIdDs, inTransaction: InTransactionEnum): Promise; } export interface IUpdateTableFilterById { - execute(inputData: UpdateTableFilterDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: UpdateTableFilterDs, inTransaction: InTransactionEnum): Promise; } diff --git a/backend/src/entities/table-filters/use-cases/update-table-filters.use.case.ts b/backend/src/entities/table-filters/use-cases/update-table-filters.use.case.ts index 0b6ed5be4..cc0dafe38 100644 --- a/backend/src/entities/table-filters/use-cases/update-table-filters.use.case.ts +++ b/backend/src/entities/table-filters/use-cases/update-table-filters.use.case.ts @@ -13,55 +13,55 @@ import { IUpdateTableFilterById } from './table-filters-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class UpdateTableFiltersUseCase - extends AbstractUseCase - implements IUpdateTableFilterById + extends AbstractUseCase + implements IUpdateTableFilterById { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(updateTableFilterData: UpdateTableFilterDs): Promise { - const { connection_id, masterPwd, filter_id } = updateTableFilterData; - const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( - connection_id, - masterPwd, - ); - if (foundConnection.is_frozen) { - throw new NonAvailableInFreePlanException(Messages.CONNECTION_IS_FROZEN); - } + protected async implementation(updateTableFilterData: UpdateTableFilterDs): Promise { + const { connection_id, masterPwd, filter_id } = updateTableFilterData; + const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( + connection_id, + masterPwd, + ); + if (foundConnection.is_frozen) { + throw new NonAvailableInFreePlanException(Messages.CONNECTION_IS_FROZEN); + } - const filtersToUpdate = await this._dbContext.tableFiltersRepository.findTableFiltersByIdAndConnectionId( - filter_id, - connection_id, - ); + const filtersToUpdate = await this._dbContext.tableFiltersRepository.findTableFiltersByIdAndConnectionId( + filter_id, + connection_id, + ); - if (!filtersToUpdate) { - throw new NotFoundException(Messages.TABLE_FILTERS_NOT_FOUND); - } + if (!filtersToUpdate) { + throw new NotFoundException(Messages.TABLE_FILTERS_NOT_FOUND); + } - const updatedTableFilterData: UpdateTableFilterValidationDs = { - ...updateTableFilterData, - table_name: filtersToUpdate.table_name, - }; + const updatedTableFilterData: UpdateTableFilterValidationDs = { + ...updateTableFilterData, + table_name: filtersToUpdate.table_name, + }; - const errors = await validateFiltersData(updatedTableFilterData, foundConnection); - if (errors.length > 0) { - throw new BadRequestException(errors.join(',\n')); - } + const errors = await validateFiltersData(updatedTableFilterData, foundConnection); + if (errors.length > 0) { + throw new BadRequestException(errors.join(',\n')); + } - const updatedFilterEntity = buildNewTableFiltersEntity(updatedTableFilterData); - for (const key in updatedFilterEntity) { - // eslint-disable-next-line security/detect-object-injection - if (updatedFilterEntity[key] === undefined) { - // eslint-disable-next-line security/detect-object-injection - delete updatedFilterEntity[key]; - } - } - const updatedFilters = Object.assign(filtersToUpdate, updatedFilterEntity); - await this._dbContext.tableFiltersRepository.save(updatedFilters); - return buildCreatedTableFilterRO(updatedFilters); - } + const updatedFilterEntity = buildNewTableFiltersEntity(updatedTableFilterData); + for (const key in updatedFilterEntity) { + // eslint-disable-next-line security/detect-object-injection + if (updatedFilterEntity[key] === undefined) { + // eslint-disable-next-line security/detect-object-injection + delete updatedFilterEntity[key]; + } + } + const updatedFilters = Object.assign(filtersToUpdate, updatedFilterEntity); + await this._dbContext.tableFiltersRepository.save(updatedFilters); + return buildCreatedTableFilterRO(updatedFilters); + } } diff --git a/backend/src/entities/table-filters/utils/build-created-table-filters-response-object.util.ts b/backend/src/entities/table-filters/utils/build-created-table-filters-response-object.util.ts index 65899462a..d16090175 100644 --- a/backend/src/entities/table-filters/utils/build-created-table-filters-response-object.util.ts +++ b/backend/src/entities/table-filters/utils/build-created-table-filters-response-object.util.ts @@ -2,20 +2,20 @@ import { CreatedTableFilterRO } from '../application/response-objects/created-ta import { TableFiltersEntity } from '../table-filters.entity.js'; export function buildCreatedTableFilterRO(tableFilters: TableFiltersEntity): CreatedTableFilterRO { - const dynamicColumnExists: boolean = - tableFilters.dynamic_filter_column_name !== null && tableFilters.dynamic_filter_comparator !== null; - return { - id: tableFilters.id, - table_name: tableFilters.table_name, - name: tableFilters.name, - filters: tableFilters.filters, - dynamic_column: dynamicColumnExists - ? { - column_name: tableFilters.dynamic_filter_column_name, - comparator: tableFilters.dynamic_filter_comparator, - } - : null, - createdAt: tableFilters.createdAt, - updatedAt: tableFilters.updatedAt, - }; + const dynamicColumnExists: boolean = + tableFilters.dynamic_filter_column_name !== null && tableFilters.dynamic_filter_comparator !== null; + return { + id: tableFilters.id, + table_name: tableFilters.table_name, + name: tableFilters.name, + filters: tableFilters.filters, + dynamic_column: dynamicColumnExists + ? { + column_name: tableFilters.dynamic_filter_column_name, + comparator: tableFilters.dynamic_filter_comparator, + } + : null, + createdAt: tableFilters.createdAt, + updatedAt: tableFilters.updatedAt, + }; } diff --git a/backend/src/entities/table-filters/utils/build-new-table-filters-entity.util.ts b/backend/src/entities/table-filters/utils/build-new-table-filters-entity.util.ts index 86e09f29a..32de4e0fb 100644 --- a/backend/src/entities/table-filters/utils/build-new-table-filters-entity.util.ts +++ b/backend/src/entities/table-filters/utils/build-new-table-filters-entity.util.ts @@ -3,27 +3,27 @@ import { TableFiltersEntity } from '../table-filters.entity.js'; import { UpdateTableFilterValidationDs } from './validate-table-filters-data.util.js'; type CreateTableFilterData = { - table_name: string; - filter_name: string; - connection_id: string; - filters: Record; - dynamic_filtered_column: DynamicTableFiltersDs | null; + table_name: string; + filter_name: string; + connection_id: string; + filters: Record; + dynamic_filtered_column: DynamicTableFiltersDs | null; }; export function buildNewTableFiltersEntity( - filterData: CreateTableFilterData | UpdateTableFilterValidationDs, + filterData: CreateTableFilterData | UpdateTableFilterValidationDs, ): TableFiltersEntity { - const newTableFilters = new TableFiltersEntity(); - newTableFilters.table_name = filterData.table_name; - newTableFilters.connectionId = filterData.connection_id; - newTableFilters.filters = filterData.filters; - newTableFilters.name = filterData.filter_name; + const newTableFilters = new TableFiltersEntity(); + newTableFilters.table_name = filterData.table_name; + newTableFilters.connectionId = filterData.connection_id; + newTableFilters.filters = filterData.filters; + newTableFilters.name = filterData.filter_name; - if (filterData.dynamic_filtered_column) { - newTableFilters.dynamic_filter_column_name = filterData.dynamic_filtered_column.column_name; - newTableFilters.dynamic_filter_comparator = filterData.dynamic_filtered_column.comparator; - } else { - newTableFilters.dynamic_filter_column_name = null; - } + if (filterData.dynamic_filtered_column) { + newTableFilters.dynamic_filter_column_name = filterData.dynamic_filtered_column.column_name; + newTableFilters.dynamic_filter_comparator = filterData.dynamic_filtered_column.comparator; + } else { + newTableFilters.dynamic_filter_column_name = null; + } - return newTableFilters; + return newTableFilters; } diff --git a/backend/src/entities/table-filters/utils/validate-table-filters-data.util.ts b/backend/src/entities/table-filters/utils/validate-table-filters-data.util.ts index 5ce2820cd..1af0c08be 100644 --- a/backend/src/entities/table-filters/utils/validate-table-filters-data.util.ts +++ b/backend/src/entities/table-filters/utils/validate-table-filters-data.util.ts @@ -7,45 +7,45 @@ import { CreateTableFilterDs } from '../application/data-structures/create-table import { UpdateTableFilterDs } from '../application/data-structures/update-table-filters.ds.js'; export class UpdateTableFilterValidationDs extends UpdateTableFilterDs { - table_name: string; + table_name: string; } export async function validateFiltersData( - inputData: CreateTableFilterDs | UpdateTableFilterValidationDs, - foundConnection: ConnectionEntity, + inputData: CreateTableFilterDs | UpdateTableFilterValidationDs, + foundConnection: ConnectionEntity, ): Promise> { - const { table_name, filters, dynamic_filtered_column } = inputData; - const errors: Array = []; - const dao = getDataAccessObject(foundConnection); - const tablesInConnection = await dao.getTablesFromDB(); - const tableNames = tablesInConnection.map((table) => table.tableName); - if (!tableNames.includes(table_name)) { - errors.push(Messages.TABLE_NOT_FOUND); - } - if (errors.length > 0) { - return errors; - } - const tableStructure = await dao.getTableStructure(table_name, null); - const tableColumnNames = tableStructure.map((el) => el.column_name); + const { table_name, filters, dynamic_filtered_column } = inputData; + const errors: Array = []; + const dao = getDataAccessObject(foundConnection); + const tablesInConnection = await dao.getTablesFromDB(); + const tableNames = tablesInConnection.map((table) => table.tableName); + if (!tableNames.includes(table_name)) { + errors.push(Messages.TABLE_NOT_FOUND); + } + if (errors.length > 0) { + return errors; + } + const tableStructure = await dao.getTableStructure(table_name, null); + const tableColumnNames = tableStructure.map((el) => el.column_name); - for (const column_name in filters) { - if (!tableColumnNames.includes(column_name)) { - errors.push(Messages.NO_SUCH_FIELD_IN_TABLE(column_name, table_name)); - } - // eslint-disable-next-line security/detect-object-injection - for (const filterCriteria in filters[column_name]) { - if (!validateStringWithEnum(filterCriteria, FilterCriteriaEnum)) { - errors.push(`Invalid filter criteria: "${filterCriteria}".`); - } - } - } - if (dynamic_filtered_column) { - if (!tableColumnNames.includes(dynamic_filtered_column.column_name)) { - errors.push(Messages.NO_SUCH_FIELD_IN_TABLE(dynamic_filtered_column.column_name, table_name)); - } - if (!validateStringWithEnum(dynamic_filtered_column.comparator, FilterCriteriaEnum)) { - errors.push(`Invalid filter criteria: "${dynamic_filtered_column.comparator}".`); - } - } - return errors; + for (const column_name in filters) { + if (!tableColumnNames.includes(column_name)) { + errors.push(Messages.NO_SUCH_FIELD_IN_TABLE(column_name, table_name)); + } + // eslint-disable-next-line security/detect-object-injection + for (const filterCriteria in filters[column_name]) { + if (!validateStringWithEnum(filterCriteria, FilterCriteriaEnum)) { + errors.push(`Invalid filter criteria: "${filterCriteria}".`); + } + } + } + if (dynamic_filtered_column) { + if (!tableColumnNames.includes(dynamic_filtered_column.column_name)) { + errors.push(Messages.NO_SUCH_FIELD_IN_TABLE(dynamic_filtered_column.column_name, table_name)); + } + if (!validateStringWithEnum(dynamic_filtered_column.comparator, FilterCriteriaEnum)) { + errors.push(`Invalid filter criteria: "${dynamic_filtered_column.comparator}".`); + } + } + return errors; } diff --git a/backend/src/entities/table-info/table-info.entity.ts b/backend/src/entities/table-info/table-info.entity.ts index 3cbf8abef..c7fb7e771 100644 --- a/backend/src/entities/table-info/table-info.entity.ts +++ b/backend/src/entities/table-info/table-info.entity.ts @@ -4,16 +4,23 @@ import { TableFieldInfoEntity } from '../table-field-info/table-field-info.entit @Entity('table_info') export class TableInfoEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column() - table_name: string; + @Column() + table_name: string; - @ManyToOne(() => ConnectionEntity, (connection) => connection.tables_info, { onDelete: 'CASCADE' }) - @JoinColumn() - connection: Relation; + @ManyToOne( + () => ConnectionEntity, + (connection) => connection.tables_info, + { onDelete: 'CASCADE' }, + ) + @JoinColumn() + connection: Relation; - @OneToMany(() => TableFieldInfoEntity, (table_field_info) => table_field_info.table_info) - table_fields_info: Relation[]; + @OneToMany( + () => TableFieldInfoEntity, + (table_field_info) => table_field_info.table_info, + ) + table_fields_info: Relation[]; } diff --git a/backend/src/entities/table-logs/application/data-structures/create-log-record.ds.ts b/backend/src/entities/table-logs/application/data-structures/create-log-record.ds.ts index 954271abb..66bc62c88 100644 --- a/backend/src/entities/table-logs/application/data-structures/create-log-record.ds.ts +++ b/backend/src/entities/table-logs/application/data-structures/create-log-record.ds.ts @@ -1,5 +1,5 @@ -import { ConnectionEntity } from '../../../connection/connection.entity.js'; import { LogOperationTypeEnum, OperationResultStatusEnum } from '../../../../enums/index.js'; +import { ConnectionEntity } from '../../../connection/connection.entity.js'; export class CreateLogRecordDs { connection: ConnectionEntity; diff --git a/backend/src/entities/table-logs/application/data-structures/created-log-record.ds.ts b/backend/src/entities/table-logs/application/data-structures/created-log-record.ds.ts index 4a19adf52..52d88d338 100644 --- a/backend/src/entities/table-logs/application/data-structures/created-log-record.ds.ts +++ b/backend/src/entities/table-logs/application/data-structures/created-log-record.ds.ts @@ -1,15 +1,15 @@ import { LogOperationTypeEnum, OperationResultStatusEnum } from '../../../../enums/index.js'; export class CreatedLogRecordDs { - connection_id: string; - createdAt: Date; - email: string; - id: string; - old_data: string; - operationStatusResult!: OperationResultStatusEnum; - operationType: LogOperationTypeEnum; - received_data: string; - affected_primary_key: string; - table_name: string; - userId: string; + connection_id: string; + createdAt: Date; + email: string; + id: string; + old_data: string; + operationStatusResult!: OperationResultStatusEnum; + operationType: LogOperationTypeEnum; + received_data: string; + affected_primary_key: string; + table_name: string; + userId: string; } diff --git a/backend/src/entities/table-logs/application/data-structures/find-logs.ds.ts b/backend/src/entities/table-logs/application/data-structures/find-logs.ds.ts index 2ad1d0c09..e8fb2fd93 100644 --- a/backend/src/entities/table-logs/application/data-structures/find-logs.ds.ts +++ b/backend/src/entities/table-logs/application/data-structures/find-logs.ds.ts @@ -1,8 +1,8 @@ import { LogOperationTypeEnum } from '../../../../enums/index.js'; export class FindLogsDs { - connectionId: string; - query: Record; - userId: string; - operationTypes: Array; + connectionId: string; + query: Record; + userId: string; + operationTypes: Array; } diff --git a/backend/src/entities/table-logs/application/data-structures/found-logs.ds.ts b/backend/src/entities/table-logs/application/data-structures/found-logs.ds.ts index 36802bc49..c3a2056e9 100644 --- a/backend/src/entities/table-logs/application/data-structures/found-logs.ds.ts +++ b/backend/src/entities/table-logs/application/data-structures/found-logs.ds.ts @@ -1,52 +1,52 @@ -import { PaginationDs } from '../../../table/application/data-structures/pagination.ds.js'; +import { ApiProperty } from '@nestjs/swagger'; import { LogOperationTypeEnum, OperationResultStatusEnum } from '../../../../enums/index.js'; +import { PaginationDs } from '../../../table/application/data-structures/pagination.ds.js'; import { TableLogsEntity } from '../../table-logs.entity.js'; -import { ApiProperty } from '@nestjs/swagger'; export class FoundLogRecordDs { - @ApiProperty() - cognitoUserName: string; + @ApiProperty() + cognitoUserName: string; - @ApiProperty() - connection_id: string; + @ApiProperty() + connection_id: string; - @ApiProperty() - createdAt: Date; + @ApiProperty() + createdAt: Date; - @ApiProperty() - email: string; + @ApiProperty() + email: string; - @ApiProperty() - old_data: string; + @ApiProperty() + old_data: string; - @ApiProperty() - affected_primary_key: string; + @ApiProperty() + affected_primary_key: string; - @ApiProperty({ enum: OperationResultStatusEnum }) - operationStatusResult: OperationResultStatusEnum; + @ApiProperty({ enum: OperationResultStatusEnum }) + operationStatusResult: OperationResultStatusEnum; - @ApiProperty({ enum: LogOperationTypeEnum }) - operationType: LogOperationTypeEnum; + @ApiProperty({ enum: LogOperationTypeEnum }) + operationType: LogOperationTypeEnum; - @ApiProperty() - received_data: string; + @ApiProperty() + received_data: string; - @ApiProperty() - table_name: string; + @ApiProperty() + table_name: string; - @ApiProperty() - operation_custom_action_name: string | null; + @ApiProperty() + operation_custom_action_name: string | null; } export class FoundLogsDs { - @ApiProperty({ isArray: true, type: FoundLogRecordDs }) - logs: Array; + @ApiProperty({ isArray: true, type: FoundLogRecordDs }) + logs: Array; - @ApiProperty({ type: PaginationDs }) - pagination: PaginationDs; + @ApiProperty({ type: PaginationDs }) + pagination: PaginationDs; } export class FoundLogsEntities { - logs: Array; - pagination: PaginationDs; + logs: Array; + pagination: PaginationDs; } diff --git a/backend/src/entities/table-logs/repository/table-logs-custom-repository-extension.ts b/backend/src/entities/table-logs/repository/table-logs-custom-repository-extension.ts index e118ee446..760908dee 100644 --- a/backend/src/entities/table-logs/repository/table-logs-custom-repository-extension.ts +++ b/backend/src/entities/table-logs/repository/table-logs-custom-repository-extension.ts @@ -1,3 +1,4 @@ +import { ReadStream } from 'typeorm/platform/PlatformTools.js'; import { UserEntity } from '../../user/user.entity.js'; import { CreateLogRecordDs } from '../application/data-structures/create-log-record.ds.js'; import { CreatedLogRecordDs } from '../application/data-structures/created-log-record.ds.js'; @@ -6,153 +7,152 @@ import { TableLogsEntity } from '../table-logs.entity.js'; import { buildCreatedLogRecord } from '../utils/build-created-log-record.js'; import { buildTableLogsEntity } from '../utils/build-table-logs-entity.js'; import { IFindLogsOptions, ITableLogsRepository } from './table-logs-repository.interface.js'; -import { ReadStream } from 'typeorm/platform/PlatformTools.js'; export const tableLogsCustomRepositoryExtension: ITableLogsRepository = { - async createLogRecord(logData: CreateLogRecordDs): Promise { - const { userId } = logData; - const userQb = this.manager - .getRepository(UserEntity) - .createQueryBuilder('user') - .where('user.id = id', { id: userId }); - const { email } = await userQb.getOne(); - const newLogRecord = buildTableLogsEntity(logData, email.toLowerCase()); - const savedLogRecord = await this.save(newLogRecord); - return buildCreatedLogRecord(savedLogRecord); - }, + async createLogRecord(logData: CreateLogRecordDs): Promise { + const { userId } = logData; + const userQb = this.manager + .getRepository(UserEntity) + .createQueryBuilder('user') + .where('user.id = id', { id: userId }); + const { email } = await userQb.getOne(); + const newLogRecord = buildTableLogsEntity(logData, email.toLowerCase()); + const savedLogRecord = await this.save(newLogRecord); + return buildCreatedLogRecord(savedLogRecord); + }, - async saveNewOrUpdatedLogRecord(logRecord: TableLogsEntity): Promise { - return await this.save(logRecord); - }, + async saveNewOrUpdatedLogRecord(logRecord: TableLogsEntity): Promise { + return await this.save(logRecord); + }, - async findLogs(findOptions: IFindLogsOptions): Promise { - const { - connectionId, - currentUserId, - dateFrom, - dateTo, - order, - page, - perPage, - searchedEmail, - tableName, - userConnectionEdit, - userInGroupsIds, - logOperationType, - logOperationTypes, - searchedAffectedPrimaryKey, - } = findOptions; - const qb = this.createQueryBuilder('tableLogs').leftJoinAndSelect('tableLogs.connection_id', 'connection_id'); - qb.andWhere('tableLogs.connection_id = :connection_id', { connection_id: connectionId }); + async findLogs(findOptions: IFindLogsOptions): Promise { + const { + connectionId, + currentUserId, + dateFrom, + dateTo, + order, + page, + perPage, + searchedEmail, + tableName, + userConnectionEdit, + userInGroupsIds, + logOperationType, + logOperationTypes, + searchedAffectedPrimaryKey, + } = findOptions; + const qb = this.createQueryBuilder('tableLogs').leftJoinAndSelect('tableLogs.connection_id', 'connection_id'); + qb.andWhere('tableLogs.connection_id = :connection_id', { connection_id: connectionId }); - if (tableName) { - qb.andWhere('tableLogs.table_name = :table_name', { table_name: tableName }); - } + if (tableName) { + qb.andWhere('tableLogs.table_name = :table_name', { table_name: tableName }); + } - if (searchedAffectedPrimaryKey) { - qb.andWhere('tableLogs.affected_primary_key LIKE :searchString', { - searchString: `%${searchedAffectedPrimaryKey}%`, - }); - } + if (searchedAffectedPrimaryKey) { + qb.andWhere('tableLogs.affected_primary_key LIKE :searchString', { + searchString: `%${searchedAffectedPrimaryKey}%`, + }); + } - if (!userConnectionEdit) { - if (userInGroupsIds.length > 0) { - for (const userId of userInGroupsIds) { - qb.orWhere('tableLogs.cognitoUserName = :userIdInAdminGroup', { userIdInAdminGroup: userId }); - } - } else { - qb.andWhere('tableLogs.cognitoUserName = :currentUserId', { currentUserId: currentUserId }); - } - } - qb.orderBy('tableLogs.createdAt', order); - if (dateFrom && dateTo) { - qb.andWhere('tableLogs.createdAt >= :date_from', { date_from: dateFrom }); - qb.andWhere('tableLogs.createdAt <= :date_to', { date_to: dateTo }); - } - if (searchedEmail) { - qb.andWhere('tableLogs.email = :searchMail', { searchMail: searchedEmail.toLowerCase() }); - } - if (logOperationType) { - qb.andWhere('tableLogs.operationType = :logOperationType', { logOperationType: logOperationType }); - } - if (logOperationTypes.length > 0) { - for (const type of logOperationTypes) { - qb.orWhere('tableLogs.operationType = :type', { type: type }); - } - } - const rowsCount = await qb.getCount(); - const lastPage = Math.ceil(rowsCount / perPage); - const offset = (page - 1) * perPage; - qb.limit(perPage); - qb.offset(offset); - const logs = await qb.getMany(); - return { - logs: logs, - pagination: { - currentPage: page, - lastPage: lastPage, - perPage: perPage, - total: rowsCount, - }, - }; - }, + if (!userConnectionEdit) { + if (userInGroupsIds.length > 0) { + for (const userId of userInGroupsIds) { + qb.orWhere('tableLogs.cognitoUserName = :userIdInAdminGroup', { userIdInAdminGroup: userId }); + } + } else { + qb.andWhere('tableLogs.cognitoUserName = :currentUserId', { currentUserId: currentUserId }); + } + } + qb.orderBy('tableLogs.createdAt', order); + if (dateFrom && dateTo) { + qb.andWhere('tableLogs.createdAt >= :date_from', { date_from: dateFrom }); + qb.andWhere('tableLogs.createdAt <= :date_to', { date_to: dateTo }); + } + if (searchedEmail) { + qb.andWhere('tableLogs.email = :searchMail', { searchMail: searchedEmail.toLowerCase() }); + } + if (logOperationType) { + qb.andWhere('tableLogs.operationType = :logOperationType', { logOperationType: logOperationType }); + } + if (logOperationTypes.length > 0) { + for (const type of logOperationTypes) { + qb.orWhere('tableLogs.operationType = :type', { type: type }); + } + } + const rowsCount = await qb.getCount(); + const lastPage = Math.ceil(rowsCount / perPage); + const offset = (page - 1) * perPage; + qb.limit(perPage); + qb.offset(offset); + const logs = await qb.getMany(); + return { + logs: logs, + pagination: { + currentPage: page, + lastPage: lastPage, + perPage: perPage, + total: rowsCount, + }, + }; + }, - async findLogsAsStream(findOptions: IFindLogsOptions): Promise { - const { - connectionId, - currentUserId, - dateFrom, - dateTo, - order, - page, - perPage, - searchedEmail, - tableName, - userConnectionEdit, - userInGroupsIds, - logOperationType, - logOperationTypes, - searchedAffectedPrimaryKey, - } = findOptions; - const qb = this.createQueryBuilder('tableLogs').leftJoinAndSelect('tableLogs.connection_id', 'connection_id'); - qb.andWhere('tableLogs.connection_id = :connection_id', { connection_id: connectionId }); - if (tableName) { - qb.andWhere('tableLogs.table_name = :table_name', { table_name: tableName }); - } - if (searchedAffectedPrimaryKey) { - qb.andWhere('tableLogs.affected_primary_key LIKE :searchString', { - searchString: `%${searchedAffectedPrimaryKey}%`, - }); - } - if (!userConnectionEdit) { - if (userInGroupsIds.length > 0) { - for (const userId of userInGroupsIds) { - qb.orWhere('tableLogs.cognitoUserName = :userIdInAdminGroup', { userIdInAdminGroup: userId }); - } - } else { - qb.andWhere('tableLogs.cognitoUserName = :currentUserId', { currentUserId: currentUserId }); - } - } - qb.orderBy('tableLogs.createdAt', order); - if (dateFrom && dateTo) { - qb.andWhere('tableLogs.createdAt >= :date_from', { date_from: dateFrom }); - qb.andWhere('tableLogs.createdAt <= :date_to', { date_to: dateTo }); - } - if (searchedEmail) { - qb.andWhere('tableLogs.email = :searchMail', { searchMail: searchedEmail.toLowerCase() }); - } - if (logOperationType) { - qb.andWhere('tableLogs.operationType = :logOperationType', { logOperationType: logOperationType }); - } - if (logOperationTypes.length > 0) { - for (const type of logOperationTypes) { - qb.orWhere('tableLogs.operationType = :type', { type: type }); - } - } + async findLogsAsStream(findOptions: IFindLogsOptions): Promise { + const { + connectionId, + currentUserId, + dateFrom, + dateTo, + order, + page, + perPage, + searchedEmail, + tableName, + userConnectionEdit, + userInGroupsIds, + logOperationType, + logOperationTypes, + searchedAffectedPrimaryKey, + } = findOptions; + const qb = this.createQueryBuilder('tableLogs').leftJoinAndSelect('tableLogs.connection_id', 'connection_id'); + qb.andWhere('tableLogs.connection_id = :connection_id', { connection_id: connectionId }); + if (tableName) { + qb.andWhere('tableLogs.table_name = :table_name', { table_name: tableName }); + } + if (searchedAffectedPrimaryKey) { + qb.andWhere('tableLogs.affected_primary_key LIKE :searchString', { + searchString: `%${searchedAffectedPrimaryKey}%`, + }); + } + if (!userConnectionEdit) { + if (userInGroupsIds.length > 0) { + for (const userId of userInGroupsIds) { + qb.orWhere('tableLogs.cognitoUserName = :userIdInAdminGroup', { userIdInAdminGroup: userId }); + } + } else { + qb.andWhere('tableLogs.cognitoUserName = :currentUserId', { currentUserId: currentUserId }); + } + } + qb.orderBy('tableLogs.createdAt', order); + if (dateFrom && dateTo) { + qb.andWhere('tableLogs.createdAt >= :date_from', { date_from: dateFrom }); + qb.andWhere('tableLogs.createdAt <= :date_to', { date_to: dateTo }); + } + if (searchedEmail) { + qb.andWhere('tableLogs.email = :searchMail', { searchMail: searchedEmail.toLowerCase() }); + } + if (logOperationType) { + qb.andWhere('tableLogs.operationType = :logOperationType', { logOperationType: logOperationType }); + } + if (logOperationTypes.length > 0) { + for (const type of logOperationTypes) { + qb.orWhere('tableLogs.operationType = :type', { type: type }); + } + } - const offset = (page - 1) * perPage; - qb.limit(perPage); - qb.offset(offset); - return qb.stream(); - }, + const offset = (page - 1) * perPage; + qb.limit(perPage); + qb.offset(offset); + return qb.stream(); + }, }; diff --git a/backend/src/entities/table-logs/repository/table-logs-repository.interface.ts b/backend/src/entities/table-logs/repository/table-logs-repository.interface.ts index 1eecff5e0..f4a0e0d20 100644 --- a/backend/src/entities/table-logs/repository/table-logs-repository.interface.ts +++ b/backend/src/entities/table-logs/repository/table-logs-repository.interface.ts @@ -6,28 +6,28 @@ import { FoundLogsEntities } from '../application/data-structures/found-logs.ds. import { TableLogsEntity } from '../table-logs.entity.js'; export interface ITableLogsRepository { - createLogRecord(logsData: CreateLogRecordDs): Promise; + createLogRecord(logsData: CreateLogRecordDs): Promise; - findLogs(findOptions: IFindLogsOptions): Promise; + findLogs(findOptions: IFindLogsOptions): Promise; - saveNewOrUpdatedLogRecord(logRecord: TableLogsEntity): Promise; + saveNewOrUpdatedLogRecord(logRecord: TableLogsEntity): Promise; - findLogsAsStream(findOptions: IFindLogsOptions): Promise; + findLogsAsStream(findOptions: IFindLogsOptions): Promise; } export interface IFindLogsOptions { - connectionId: string; - currentUserId: string; - dateFrom: Date; - dateTo: Date; - order: QueryOrderingEnum; - page: number; - perPage: number; - searchedEmail: string; - tableName: string; - userConnectionEdit: boolean; - userInGroupsIds: Array; - logOperationType: LogOperationTypeEnum; - logOperationTypes: Array; - searchedAffectedPrimaryKey: string; + connectionId: string; + currentUserId: string; + dateFrom: Date; + dateTo: Date; + order: QueryOrderingEnum; + page: number; + perPage: number; + searchedEmail: string; + tableName: string; + userConnectionEdit: boolean; + userInGroupsIds: Array; + logOperationType: LogOperationTypeEnum; + logOperationTypes: Array; + searchedAffectedPrimaryKey: string; } diff --git a/backend/src/entities/table-logs/table-logs.controller.ts b/backend/src/entities/table-logs/table-logs.controller.ts index 0293f444a..73f71f41c 100644 --- a/backend/src/entities/table-logs/table-logs.controller.ts +++ b/backend/src/entities/table-logs/table-logs.controller.ts @@ -10,16 +10,16 @@ import { UseInterceptors, } from '@nestjs/common'; import { HttpException } from '@nestjs/common/exceptions/http.exception.js'; +import { ApiBearerAuth, ApiOperation, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger'; import { UseCaseType } from '../../common/data-injection.tokens.js'; import { SlugUuid, UserId } from '../../decorators/index.js'; +import { Timeout } from '../../decorators/timeout.decorator.js'; import { InTransactionEnum, LogOperationTypeEnum } from '../../enums/index.js'; import { Messages } from '../../exceptions/text/messages.js'; import { SentryInterceptor } from '../../interceptors/index.js'; import { FindLogsDs } from './application/data-structures/find-logs.ds.js'; import { FoundLogsDs } from './application/data-structures/found-logs.ds.js'; import { IExportLogsAsCsv, IFindLogs } from './use-cases/use-cases.interface.js'; -import { ApiBearerAuth, ApiOperation, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger'; -import { Timeout } from '../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/table-logs/table-logs.entity.ts b/backend/src/entities/table-logs/table-logs.entity.ts index b7da56cd9..50f761f0d 100644 --- a/backend/src/entities/table-logs/table-logs.entity.ts +++ b/backend/src/entities/table-logs/table-logs.entity.ts @@ -1,102 +1,106 @@ +import { Transform } from 'class-transformer'; import sjson from 'secure-json-parse'; import { - AfterLoad, - BeforeInsert, - Column, - Entity, - JoinColumn, - ManyToOne, - PrimaryGeneratedColumn, - Relation, + AfterLoad, + BeforeInsert, + Column, + Entity, + JoinColumn, + ManyToOne, + PrimaryGeneratedColumn, + Relation, } from 'typeorm'; -import { ConnectionEntity } from '../connection/connection.entity.js'; import { LogOperationTypeEnum, OperationResultStatusEnum } from '../../enums/index.js'; -import { Transform } from 'class-transformer'; +import { ConnectionEntity } from '../connection/connection.entity.js'; @Entity('tableLogs') export class TableLogsEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ default: null }) - table_name: string; + @Column({ default: null }) + table_name: string; - @Column({ default: null }) - affected_primary_key: string; + @Column({ default: null }) + affected_primary_key: string; - @Column({ default: null }) - received_data: string; + @Column({ default: null }) + received_data: string; - @Column({ default: null }) - old_data: string; + @Column({ default: null }) + old_data: string; - @Column({ default: null }) - cognitoUserName: string; + @Column({ default: null }) + cognitoUserName: string; - @Column({ default: null }) - email: string; + @Column({ default: null }) + email: string; - @Column({ default: null }) - operation_custom_action_name: string | null; + @Column({ default: null }) + operation_custom_action_name: string | null; - @Column('enum', { - nullable: false, - enum: LogOperationTypeEnum, - default: LogOperationTypeEnum.unknown, - }) - operationType!: LogOperationTypeEnum; + @Column('enum', { + nullable: false, + enum: LogOperationTypeEnum, + default: LogOperationTypeEnum.unknown, + }) + operationType!: LogOperationTypeEnum; - @Column('enum', { - nullable: false, - enum: OperationResultStatusEnum, - default: OperationResultStatusEnum.unknown, - }) - operationStatusResult!: OperationResultStatusEnum; + @Column('enum', { + nullable: false, + enum: OperationResultStatusEnum, + default: OperationResultStatusEnum.unknown, + }) + operationStatusResult!: OperationResultStatusEnum; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - createdAt: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + createdAt: Date; - @BeforeInsert() - stringifyRow() { - if (this.old_data) { - this.old_data = JSON.stringify(this.old_data); - } - if (this.received_data) { - this.received_data = JSON.stringify(this.received_data); - } - if(this.affected_primary_key) { - this.affected_primary_key = JSON.stringify(this.affected_primary_key); - } - } + @BeforeInsert() + stringifyRow() { + if (this.old_data) { + this.old_data = JSON.stringify(this.old_data); + } + if (this.received_data) { + this.received_data = JSON.stringify(this.received_data); + } + if (this.affected_primary_key) { + this.affected_primary_key = JSON.stringify(this.affected_primary_key); + } + } - @AfterLoad() - parseRow() { - try { - if (this.old_data) { - this.old_data = sjson.parse(this.old_data, null, { - protoAction: 'remove', - constructorAction: 'remove', - }); - } - if (this.received_data) { - this.received_data = sjson.parse(this.received_data, null, { - protoAction: 'remove', - constructorAction: 'remove', - }); - } - if(this.affected_primary_key) { - this.affected_primary_key = sjson.parse(this.affected_primary_key, null, { - protoAction: 'remove', - constructorAction: 'remove', - }); - } - } catch (_e) {} - } + @AfterLoad() + parseRow() { + try { + if (this.old_data) { + this.old_data = sjson.parse(this.old_data, null, { + protoAction: 'remove', + constructorAction: 'remove', + }); + } + if (this.received_data) { + this.received_data = sjson.parse(this.received_data, null, { + protoAction: 'remove', + constructorAction: 'remove', + }); + } + if (this.affected_primary_key) { + this.affected_primary_key = sjson.parse(this.affected_primary_key, null, { + protoAction: 'remove', + constructorAction: 'remove', + }); + } + } catch (_e) {} + } - @Transform((connection: any) => connection.id) - @ManyToOne((_) => ConnectionEntity, (connection) => connection.logs, { - onDelete: 'CASCADE', - }) - @JoinColumn() - connection_id: Relation; + @Transform((connection: any) => connection.id) + @ManyToOne( + (_) => ConnectionEntity, + (connection) => connection.logs, + { + onDelete: 'CASCADE', + }, + ) + @JoinColumn() + connection_id: Relation; } diff --git a/backend/src/entities/table-logs/table-logs.module.ts b/backend/src/entities/table-logs/table-logs.module.ts index 1ab38b151..703cb3a28 100644 --- a/backend/src/entities/table-logs/table-logs.module.ts +++ b/backend/src/entities/table-logs/table-logs.module.ts @@ -3,53 +3,53 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { AuthMiddleware } from '../../authorization/index.js'; import { GlobalDatabaseContext } from '../../common/application/global-database-context.js'; import { BaseType, UseCaseType } from '../../common/data-injection.tokens.js'; +import { ConnectionPropertiesEntity } from '../connection-properties/connection-properties.entity.js'; import { LogOutEntity } from '../log-out/log-out.entity.js'; import { TableSettingsEntity } from '../table-settings/common-table-settings/table-settings.entity.js'; import { UserEntity } from '../user/user.entity.js'; import { TableLogsController } from './table-logs.controller.js'; import { TableLogsEntity } from './table-logs.entity.js'; import { TableLogsService } from './table-logs.service.js'; -import { FindLogsUseCase } from './use-cases/find-logs.use.case.js'; -import { ConnectionPropertiesEntity } from '../connection-properties/connection-properties.entity.js'; import { ExportLogsAsCsvUseCase } from './use-cases/export-logs-as-csv.use.case.js'; +import { FindLogsUseCase } from './use-cases/find-logs.use.case.js'; @Global() @Module({ - imports: [ - TypeOrmModule.forFeature([ - TableLogsEntity, - UserEntity, - LogOutEntity, - TableSettingsEntity, - ConnectionPropertiesEntity, - ]), - ], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.FIND_LOGS, - useClass: FindLogsUseCase, - }, - { - provide: UseCaseType.EXPORT_LOGS_AS_CSV, - useClass: ExportLogsAsCsvUseCase, - }, - TableLogsService, - ], - controllers: [TableLogsController], - exports: [TableLogsService], + imports: [ + TypeOrmModule.forFeature([ + TableLogsEntity, + UserEntity, + LogOutEntity, + TableSettingsEntity, + ConnectionPropertiesEntity, + ]), + ], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.FIND_LOGS, + useClass: FindLogsUseCase, + }, + { + provide: UseCaseType.EXPORT_LOGS_AS_CSV, + useClass: ExportLogsAsCsvUseCase, + }, + TableLogsService, + ], + controllers: [TableLogsController], + exports: [TableLogsService], }) export class TableLogsModule { - public configure(consumer: MiddlewareConsumer): any { - consumer - .apply(AuthMiddleware) - .forRoutes( - { path: '/logs/:connectionId', method: RequestMethod.GET }, - { path: '/logs/', method: RequestMethod.DELETE }, - { path: '/logs/export/:connectionId', method: RequestMethod.GET }, - ); - } + public configure(consumer: MiddlewareConsumer): any { + consumer + .apply(AuthMiddleware) + .forRoutes( + { path: '/logs/:connectionId', method: RequestMethod.GET }, + { path: '/logs/', method: RequestMethod.DELETE }, + { path: '/logs/export/:connectionId', method: RequestMethod.GET }, + ); + } } diff --git a/backend/src/entities/table-logs/table-logs.service.ts b/backend/src/entities/table-logs/table-logs.service.ts index c39e1e20a..8695c15e7 100644 --- a/backend/src/entities/table-logs/table-logs.service.ts +++ b/backend/src/entities/table-logs/table-logs.service.ts @@ -5,7 +5,9 @@ import PQueue from 'p-queue'; import { Repository } from 'typeorm'; import { LogOperationTypeEnum, OperationResultStatusEnum } from '../../enums/index.js'; import { Constants } from '../../helpers/constants/constants.js'; +import { isObjectPropertyExists } from '../../helpers/validators/is-object-property-exists-validator.js'; import { ConnectionEntity } from '../connection/connection.entity.js'; +import { ConnectionPropertiesEntity } from '../connection-properties/connection-properties.entity.js'; import { TableSettingsEntity } from '../table-settings/common-table-settings/table-settings.entity.js'; import { UserEntity } from '../user/user.entity.js'; import { CreateLogRecordDs } from './application/data-structures/create-log-record.ds.js'; @@ -13,234 +15,232 @@ import { CreatedLogRecordDs } from './application/data-structures/created-log-re import { TableLogsEntity } from './table-logs.entity.js'; import { buildCreatedLogRecord } from './utils/build-created-log-record.js'; import { buildTableLogsEntity } from './utils/build-table-logs-entity.js'; -import { ConnectionPropertiesEntity } from '../connection-properties/connection-properties.entity.js'; -import { isObjectPropertyExists } from '../../helpers/validators/is-object-property-exists-validator.js'; @Injectable() export class TableLogsService { - constructor( - @InjectRepository(TableLogsEntity) - private readonly tableLogsRepository: Repository, - @InjectRepository(UserEntity) - private readonly userRepository: Repository, - @InjectRepository(TableSettingsEntity) - private readonly tableSettingsRepository: Repository, - @InjectRepository(ConnectionPropertiesEntity) - private readonly connectionPropertiesRepository: Repository, - ) {} - - public async crateAndSaveNewLogUtil(logData: CreateLogRecordDs): Promise { - const { userId, connection, table_name, old_data, row } = logData; - const isAuditEnabled = await this.isTableAuditEnabledInConnectionProperties(connection.id); - if (!isAuditEnabled) { - return; - } - const foundUser = await this.userRepository.findOne({ where: { id: userId } }); - const { email } = foundUser; - const tableSettingsQb = this.tableSettingsRepository - .createQueryBuilder('tableLogs') - .leftJoinAndSelect('tableLogs.connection_id', 'connection_id') - .andWhere('tableLogs.connection_id = :connection_id', { connection_id: connection.id }) - .andWhere('tableLogs.table_name = :table_name', { table_name: table_name }); - - const tableSettings = await tableSettingsQb.getOne(); - const sensitive_fields = tableSettings?.sensitive_fields; - - if (sensitive_fields && sensitive_fields.length > 0) { - for (const fieldName of sensitive_fields) { - if ( - old_data && - typeof old_data === 'object' && - isObjectPropertyExists(old_data, fieldName) && - row && - typeof row === 'object' && - isObjectPropertyExists(row, fieldName) - ) { - // eslint-disable-next-line security/detect-object-injection - if (this.compareValues(old_data[fieldName], row[fieldName])) { - // eslint-disable-next-line security/detect-object-injection - old_data[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_CHANGED; - // eslint-disable-next-line security/detect-object-injection - row[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_CHANGED; - } else { - // eslint-disable-next-line security/detect-object-injection - old_data[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_NOT_CHANGED; - // eslint-disable-next-line security/detect-object-injection - row[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_CHANGED; - } - } else { - if (old_data && typeof old_data === 'object' && isObjectPropertyExists(old_data, fieldName)) { - // eslint-disable-next-line security/detect-object-injection - old_data[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_NOT_CHANGED; - } - if (row && typeof row === 'object' && isObjectPropertyExists(row, fieldName)) { - // eslint-disable-next-line security/detect-object-injection - row[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_CHANGED; - } - } - } - } - - if (typeof old_data === 'string') { - const sensitiveValues = findSensitiveValues([old_data]); - if (sensitiveValues && sensitiveValues.length > 0) { - scrub(old_data, sensitiveValues); - } - } - - if (typeof row === 'string') { - const sensitiveValues = findSensitiveValues([row]); - scrub(row, sensitiveValues); - } - - if (old_data && typeof old_data === 'object') { - const sensitiveValues = findSensitiveValues(old_data); - if (sensitiveValues && sensitiveValues.length > 0) { - scrub(old_data, sensitiveValues); - } - } - - if (row && typeof row === 'object') { - const sensitiveValues = findSensitiveValues(row); - if (sensitiveValues && sensitiveValues.length > 0) { - scrub(row, sensitiveValues); - } - } - - const newLogRecord = buildTableLogsEntity(logData, email); - const savedLogRecord = await this.tableLogsRepository.save(newLogRecord); - return buildCreatedLogRecord(savedLogRecord); - } - - public async createAndSaveNewLogsUtil( - logsData: Array<{ - operationStatusResult: OperationResultStatusEnum; - row: Record; - old_data: Record; - affected_primary_key: string; - }>, - userId: string, - connection: ConnectionEntity, - table_name: string, - operationType: LogOperationTypeEnum, - ): Promise> { - const isAuditEnabled = await this.isTableAuditEnabledInConnectionProperties(connection.id); - if (!isAuditEnabled) { - return; - } - const foundUser = await this.userRepository.findOne({ where: { id: userId } }); - const { email } = foundUser; - const tableSettingsQb = this.tableSettingsRepository - .createQueryBuilder('tableLogs') - .leftJoinAndSelect('tableLogs.connection_id', 'connection_id') - .andWhere('tableLogs.connection_id = :connection_id', { connection_id: connection.id }) - .andWhere('tableLogs.table_name = :table_name', { table_name: table_name }); - - const tableSettings = await tableSettingsQb.getOne(); - const sensitive_fields = tableSettings?.sensitive_fields || []; - - const tableLogsEntities: Array = []; - for (const logData of logsData) { - const { row, old_data } = logData; - for (const fieldName of sensitive_fields) { - if ( - old_data && - typeof old_data === 'object' && - isObjectPropertyExists(old_data, fieldName) && - row && - typeof row === 'object' && - isObjectPropertyExists(row, fieldName) - ) { - // eslint-disable-next-line security/detect-object-injection - if (this.compareValues(old_data[fieldName], row[fieldName])) { - // eslint-disable-next-line security/detect-object-injection - old_data[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_CHANGED; - // eslint-disable-next-line security/detect-object-injection - row[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_CHANGED; - } else { - // eslint-disable-next-line security/detect-object-injection - old_data[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_NOT_CHANGED; - // eslint-disable-next-line security/detect-object-injection - row[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_CHANGED; - } - } else { - if (old_data && typeof old_data === 'object' && isObjectPropertyExists(old_data, fieldName)) { - // eslint-disable-next-line security/detect-object-injection - old_data[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_NOT_CHANGED; - } - - if (row && typeof row === 'object' && isObjectPropertyExists(row, fieldName)) { - // eslint-disable-next-line security/detect-object-injection - row[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_CHANGED; - } - } - } - - if (typeof old_data === 'string') { - const sensitiveValues = findSensitiveValues([old_data]); - if (sensitiveValues && sensitiveValues.length > 0) { - scrub(old_data, sensitiveValues); - } - } - - if (typeof row === 'string') { - const sensitiveValues = findSensitiveValues([row]); - scrub(row, sensitiveValues); - } - - if (old_data && typeof old_data === 'object') { - const sensitiveValues = findSensitiveValues(old_data); - if (sensitiveValues && sensitiveValues.length > 0) { - scrub(old_data, sensitiveValues); - } - } - - if (row && typeof row === 'object') { - const sensitiveValues = findSensitiveValues(row); - if (sensitiveValues && sensitiveValues.length > 0) { - scrub(row, sensitiveValues); - } - } - const loggedData: CreateLogRecordDs = { - ...logData, - connection, - table_name, - userId, - operationType, - }; - const newLogRecord = buildTableLogsEntity(loggedData, email); - tableLogsEntities.push(newLogRecord); - } - const queue = new PQueue({ concurrency: 2 }); - const createdLogs: Array = await Promise.all( - tableLogsEntities.map(async (newLogRecord) => { - return await queue.add(async () => { - const savedLogRecord = await this.tableLogsRepository.save(newLogRecord); - return buildCreatedLogRecord(savedLogRecord); - }); - }), - ); - return createdLogs.filter((log) => log) as Array; - } - - private async isTableAuditEnabledInConnectionProperties(connectionId: string): Promise { - const connectionProperties = await this.connectionPropertiesRepository.findOne({ - where: { connection: { id: connectionId } }, - }); - if (!connectionProperties) { - return true; - } - return connectionProperties.tables_audit; - } - - private compareValues(val1: any, val2: any): boolean { - if (val1 instanceof Date === true && val2 instanceof Date) { - const date1 = new Date(val1); - const date2 = new Date(val2); - const date1Parsed = date1.getTime(); - const date2Parsed = date2.getTime(); - return date1Parsed === date2Parsed; - } - return val1 === val2; - } + constructor( + @InjectRepository(TableLogsEntity) + private readonly tableLogsRepository: Repository, + @InjectRepository(UserEntity) + private readonly userRepository: Repository, + @InjectRepository(TableSettingsEntity) + private readonly tableSettingsRepository: Repository, + @InjectRepository(ConnectionPropertiesEntity) + private readonly connectionPropertiesRepository: Repository, + ) {} + + public async crateAndSaveNewLogUtil(logData: CreateLogRecordDs): Promise { + const { userId, connection, table_name, old_data, row } = logData; + const isAuditEnabled = await this.isTableAuditEnabledInConnectionProperties(connection.id); + if (!isAuditEnabled) { + return; + } + const foundUser = await this.userRepository.findOne({ where: { id: userId } }); + const { email } = foundUser; + const tableSettingsQb = this.tableSettingsRepository + .createQueryBuilder('tableLogs') + .leftJoinAndSelect('tableLogs.connection_id', 'connection_id') + .andWhere('tableLogs.connection_id = :connection_id', { connection_id: connection.id }) + .andWhere('tableLogs.table_name = :table_name', { table_name: table_name }); + + const tableSettings = await tableSettingsQb.getOne(); + const sensitive_fields = tableSettings?.sensitive_fields; + + if (sensitive_fields && sensitive_fields.length > 0) { + for (const fieldName of sensitive_fields) { + if ( + old_data && + typeof old_data === 'object' && + isObjectPropertyExists(old_data, fieldName) && + row && + typeof row === 'object' && + isObjectPropertyExists(row, fieldName) + ) { + // eslint-disable-next-line security/detect-object-injection + if (this.compareValues(old_data[fieldName], row[fieldName])) { + // eslint-disable-next-line security/detect-object-injection + old_data[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_CHANGED; + // eslint-disable-next-line security/detect-object-injection + row[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_CHANGED; + } else { + // eslint-disable-next-line security/detect-object-injection + old_data[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_NOT_CHANGED; + // eslint-disable-next-line security/detect-object-injection + row[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_CHANGED; + } + } else { + if (old_data && typeof old_data === 'object' && isObjectPropertyExists(old_data, fieldName)) { + // eslint-disable-next-line security/detect-object-injection + old_data[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_NOT_CHANGED; + } + if (row && typeof row === 'object' && isObjectPropertyExists(row, fieldName)) { + // eslint-disable-next-line security/detect-object-injection + row[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_CHANGED; + } + } + } + } + + if (typeof old_data === 'string') { + const sensitiveValues = findSensitiveValues([old_data]); + if (sensitiveValues && sensitiveValues.length > 0) { + scrub(old_data, sensitiveValues); + } + } + + if (typeof row === 'string') { + const sensitiveValues = findSensitiveValues([row]); + scrub(row, sensitiveValues); + } + + if (old_data && typeof old_data === 'object') { + const sensitiveValues = findSensitiveValues(old_data); + if (sensitiveValues && sensitiveValues.length > 0) { + scrub(old_data, sensitiveValues); + } + } + + if (row && typeof row === 'object') { + const sensitiveValues = findSensitiveValues(row); + if (sensitiveValues && sensitiveValues.length > 0) { + scrub(row, sensitiveValues); + } + } + + const newLogRecord = buildTableLogsEntity(logData, email); + const savedLogRecord = await this.tableLogsRepository.save(newLogRecord); + return buildCreatedLogRecord(savedLogRecord); + } + + public async createAndSaveNewLogsUtil( + logsData: Array<{ + operationStatusResult: OperationResultStatusEnum; + row: Record; + old_data: Record; + affected_primary_key: string; + }>, + userId: string, + connection: ConnectionEntity, + table_name: string, + operationType: LogOperationTypeEnum, + ): Promise> { + const isAuditEnabled = await this.isTableAuditEnabledInConnectionProperties(connection.id); + if (!isAuditEnabled) { + return; + } + const foundUser = await this.userRepository.findOne({ where: { id: userId } }); + const { email } = foundUser; + const tableSettingsQb = this.tableSettingsRepository + .createQueryBuilder('tableLogs') + .leftJoinAndSelect('tableLogs.connection_id', 'connection_id') + .andWhere('tableLogs.connection_id = :connection_id', { connection_id: connection.id }) + .andWhere('tableLogs.table_name = :table_name', { table_name: table_name }); + + const tableSettings = await tableSettingsQb.getOne(); + const sensitive_fields = tableSettings?.sensitive_fields || []; + + const tableLogsEntities: Array = []; + for (const logData of logsData) { + const { row, old_data } = logData; + for (const fieldName of sensitive_fields) { + if ( + old_data && + typeof old_data === 'object' && + isObjectPropertyExists(old_data, fieldName) && + row && + typeof row === 'object' && + isObjectPropertyExists(row, fieldName) + ) { + // eslint-disable-next-line security/detect-object-injection + if (this.compareValues(old_data[fieldName], row[fieldName])) { + // eslint-disable-next-line security/detect-object-injection + old_data[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_CHANGED; + // eslint-disable-next-line security/detect-object-injection + row[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_CHANGED; + } else { + // eslint-disable-next-line security/detect-object-injection + old_data[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_NOT_CHANGED; + // eslint-disable-next-line security/detect-object-injection + row[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_CHANGED; + } + } else { + if (old_data && typeof old_data === 'object' && isObjectPropertyExists(old_data, fieldName)) { + // eslint-disable-next-line security/detect-object-injection + old_data[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_NOT_CHANGED; + } + + if (row && typeof row === 'object' && isObjectPropertyExists(row, fieldName)) { + // eslint-disable-next-line security/detect-object-injection + row[fieldName] = Constants.REMOVED_SENSITIVE_FIELD_IF_CHANGED; + } + } + } + + if (typeof old_data === 'string') { + const sensitiveValues = findSensitiveValues([old_data]); + if (sensitiveValues && sensitiveValues.length > 0) { + scrub(old_data, sensitiveValues); + } + } + + if (typeof row === 'string') { + const sensitiveValues = findSensitiveValues([row]); + scrub(row, sensitiveValues); + } + + if (old_data && typeof old_data === 'object') { + const sensitiveValues = findSensitiveValues(old_data); + if (sensitiveValues && sensitiveValues.length > 0) { + scrub(old_data, sensitiveValues); + } + } + + if (row && typeof row === 'object') { + const sensitiveValues = findSensitiveValues(row); + if (sensitiveValues && sensitiveValues.length > 0) { + scrub(row, sensitiveValues); + } + } + const loggedData: CreateLogRecordDs = { + ...logData, + connection, + table_name, + userId, + operationType, + }; + const newLogRecord = buildTableLogsEntity(loggedData, email); + tableLogsEntities.push(newLogRecord); + } + const queue = new PQueue({ concurrency: 2 }); + const createdLogs: Array = await Promise.all( + tableLogsEntities.map(async (newLogRecord) => { + return await queue.add(async () => { + const savedLogRecord = await this.tableLogsRepository.save(newLogRecord); + return buildCreatedLogRecord(savedLogRecord); + }); + }), + ); + return createdLogs.filter((log) => log) as Array; + } + + private async isTableAuditEnabledInConnectionProperties(connectionId: string): Promise { + const connectionProperties = await this.connectionPropertiesRepository.findOne({ + where: { connection: { id: connectionId } }, + }); + if (!connectionProperties) { + return true; + } + return connectionProperties.tables_audit; + } + + private compareValues(val1: any, val2: any): boolean { + if (val1 instanceof Date === true && val2 instanceof Date) { + const date1 = new Date(val1); + const date2 = new Date(val2); + const date1Parsed = date1.getTime(); + const date2Parsed = date2.getTime(); + return date1Parsed === date2Parsed; + } + return val1 === val2; + } } diff --git a/backend/src/entities/table-logs/use-cases/export-logs-as-csv.use.case.ts b/backend/src/entities/table-logs/use-cases/export-logs-as-csv.use.case.ts index ee2969722..d9b129ca8 100644 --- a/backend/src/entities/table-logs/use-cases/export-logs-as-csv.use.case.ts +++ b/backend/src/entities/table-logs/use-cases/export-logs-as-csv.use.case.ts @@ -1,147 +1,147 @@ import { HttpException, HttpStatus, Inject, Injectable, StreamableFile } from '@nestjs/common'; +import * as csv from 'csv'; +import { Transform } from 'stream'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { FindLogsDs } from '../application/data-structures/find-logs.ds.js'; -import { IExportLogsAsCsv } from './use-cases.interface.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import * as csv from 'csv'; import { LogOperationTypeEnum } from '../../../enums/log-operation-type.enum.js'; -import { Messages } from '../../../exceptions/text/messages.js'; -import { validateStringWithEnum } from '../../../helpers/validators/validate-string-with-enum.js'; import { QueryOrderingEnum } from '../../../enums/query-ordering.enum.js'; +import { Messages } from '../../../exceptions/text/messages.js'; import { Constants } from '../../../helpers/constants/constants.js'; +import { validateStringWithEnum } from '../../../helpers/validators/validate-string-with-enum.js'; +import { FindLogsDs } from '../application/data-structures/find-logs.ds.js'; import { IFindLogsOptions } from '../repository/table-logs-repository.interface.js'; -import { Transform } from 'stream'; +import { IExportLogsAsCsv } from './use-cases.interface.js'; @Injectable() export class ExportLogsAsCsvUseCase extends AbstractUseCase implements IExportLogsAsCsv { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - public async implementation(inputData: FindLogsDs): Promise { - const { connectionId, query, userId, operationTypes } = inputData; - const userConnectionEdit = await this._dbContext.userAccessRepository.checkUserConnectionEdit(userId, connectionId); - const tableName = query.tableName; - let order = query.order; - let limit: string | number = query.limit; - let page = parseInt(query.page, 10); - let perPage: string | number = parseInt(query.perPage, 10); - const dateFrom = query.dateFrom; - const dateTo = query.dateTo; - const searchedEmail = query.email?.toLowerCase(); - const operationType = query.operationType as LogOperationTypeEnum; - const searchedAffectedPrimaryKey: string = query.affected_primary_key; + public async implementation(inputData: FindLogsDs): Promise { + const { connectionId, query, userId, operationTypes } = inputData; + const userConnectionEdit = await this._dbContext.userAccessRepository.checkUserConnectionEdit(userId, connectionId); + const tableName = query.tableName; + let order = query.order; + let limit: string | number = query.limit; + let page = parseInt(query.page, 10); + let perPage: string | number = parseInt(query.perPage, 10); + const dateFrom = query.dateFrom; + const dateTo = query.dateTo; + const searchedEmail = query.email?.toLowerCase(); + const operationType = query.operationType as LogOperationTypeEnum; + const searchedAffectedPrimaryKey: string = query.affected_primary_key; - if (operationType) { - const actionValidationResult = validateStringWithEnum(operationType, LogOperationTypeEnum); - if (!actionValidationResult) { - throw new HttpException( - { - message: Messages.INCORRECT_TABLE_LOG_ACTION_TYPE, - }, - HttpStatus.BAD_REQUEST, - ); - } - } - if (operationTypes.length > 0) { - for (const operationTypeElement of operationTypes) { - const actionValidationResult = validateStringWithEnum(operationTypeElement, LogOperationTypeEnum); - if (!actionValidationResult) { - throw new HttpException( - { - message: Messages.INCORRECT_TABLE_LOG_ACTION_TYPE, - }, - HttpStatus.BAD_REQUEST, - ); - } - } - } + if (operationType) { + const actionValidationResult = validateStringWithEnum(operationType, LogOperationTypeEnum); + if (!actionValidationResult) { + throw new HttpException( + { + message: Messages.INCORRECT_TABLE_LOG_ACTION_TYPE, + }, + HttpStatus.BAD_REQUEST, + ); + } + } + if (operationTypes.length > 0) { + for (const operationTypeElement of operationTypes) { + const actionValidationResult = validateStringWithEnum(operationTypeElement, LogOperationTypeEnum); + if (!actionValidationResult) { + throw new HttpException( + { + message: Messages.INCORRECT_TABLE_LOG_ACTION_TYPE, + }, + HttpStatus.BAD_REQUEST, + ); + } + } + } - if (!order || order !== QueryOrderingEnum.ASC) { - order = QueryOrderingEnum.DESC; - } - if (!limit) { - limit = Constants.DEFAULT_LOG_ROWS_LIMIT; - } - if (!page || page <= 0) { - page = 1; - } - if (!perPage || perPage <= 0) { - perPage = limit; - } + if (!order || order !== QueryOrderingEnum.ASC) { + order = QueryOrderingEnum.DESC; + } + if (!limit) { + limit = Constants.DEFAULT_LOG_ROWS_LIMIT; + } + if (!page || page <= 0) { + page = 1; + } + if (!perPage || perPage <= 0) { + perPage = limit; + } - let searchedDateFrom: Date = null; - let searchedDateTo: Date = null; - if (dateFrom && dateTo) { - let dateFromParsed = Date.parse(dateFrom); - let dateToParsed = Date.parse(dateTo); - const dateFromMs = new Date(dateFromParsed).getTime(); - const dateToMs = new Date(dateToParsed).getTime(); - if (dateFromMs > dateToMs) { - const tmpDate = dateFromParsed; - dateFromParsed = dateToParsed; - dateToParsed = tmpDate; - } - searchedDateFrom = new Date(dateFromParsed); - searchedDateTo = new Date(dateToParsed); - } + let searchedDateFrom: Date = null; + let searchedDateTo: Date = null; + if (dateFrom && dateTo) { + let dateFromParsed = Date.parse(dateFrom); + let dateToParsed = Date.parse(dateTo); + const dateFromMs = new Date(dateFromParsed).getTime(); + const dateToMs = new Date(dateToParsed).getTime(); + if (dateFromMs > dateToMs) { + const tmpDate = dateFromParsed; + dateFromParsed = dateToParsed; + dateToParsed = tmpDate; + } + searchedDateFrom = new Date(dateFromParsed); + searchedDateTo = new Date(dateToParsed); + } - let userIdsInGroupsWhereUserIsAdmin: Array = []; - if (!userConnectionEdit) { - const usersInGroupsWhereUserIsAdmin = await this._dbContext.groupRepository.findAllUsersInGroupsWhereUserIsAdmin( - userId, - connectionId, - ); - userIdsInGroupsWhereUserIsAdmin = usersInGroupsWhereUserIsAdmin.map((user) => user.id); - } + let userIdsInGroupsWhereUserIsAdmin: Array = []; + if (!userConnectionEdit) { + const usersInGroupsWhereUserIsAdmin = await this._dbContext.groupRepository.findAllUsersInGroupsWhereUserIsAdmin( + userId, + connectionId, + ); + userIdsInGroupsWhereUserIsAdmin = usersInGroupsWhereUserIsAdmin.map((user) => user.id); + } - const findOptions: IFindLogsOptions = { - connectionId: connectionId, - currentUserId: userId, - dateFrom: searchedDateFrom, - dateTo: searchedDateTo, - order: order as QueryOrderingEnum, - page: page, - perPage: perPage as number, - searchedEmail: searchedEmail, - tableName: tableName ? tableName : null, - userConnectionEdit: userConnectionEdit, - userInGroupsIds: userIdsInGroupsWhereUserIsAdmin, - logOperationType: operationType, - logOperationTypes: operationTypes, - searchedAffectedPrimaryKey: searchedAffectedPrimaryKey, - }; + const findOptions: IFindLogsOptions = { + connectionId: connectionId, + currentUserId: userId, + dateFrom: searchedDateFrom, + dateTo: searchedDateTo, + order: order as QueryOrderingEnum, + page: page, + perPage: perPage as number, + searchedEmail: searchedEmail, + tableName: tableName ? tableName : null, + userConnectionEdit: userConnectionEdit, + userInGroupsIds: userIdsInGroupsWhereUserIsAdmin, + logOperationType: operationType, + logOperationTypes: operationTypes, + searchedAffectedPrimaryKey: searchedAffectedPrimaryKey, + }; - const logsAsStream = await this._dbContext.tableLogsRepository.findLogsAsStream(findOptions); + const logsAsStream = await this._dbContext.tableLogsRepository.findLogsAsStream(findOptions); - const transformStream = new Transform({ - objectMode: true, - transform(chunk, _encoding, callback) { - const affectedPrimaryKey = JSON.parse(chunk.tableLogs_affected_primary_key || '{}'); - const transformedChunk = { - log_id: chunk.tableLogs_id, - user_id: chunk.tableLogs_cognitoUserName, - user_email: chunk.tableLogs_email, - log_operation_type: chunk.tableLogs_operationType, - log_operation_result: chunk.tableLogs_operationStatusResult, - logged_at: chunk.tableLogs_createdAt, - connection_id: chunk.tableLogs_connectionIdId, - connection_title: chunk.connection_id_title, - table_name: chunk.tableLogs_table_name, - ...affectedPrimaryKey, - }; + const transformStream = new Transform({ + objectMode: true, + transform(chunk, _encoding, callback) { + const affectedPrimaryKey = JSON.parse(chunk.tableLogs_affected_primary_key || '{}'); + const transformedChunk = { + log_id: chunk.tableLogs_id, + user_id: chunk.tableLogs_cognitoUserName, + user_email: chunk.tableLogs_email, + log_operation_type: chunk.tableLogs_operationType, + log_operation_result: chunk.tableLogs_operationStatusResult, + logged_at: chunk.tableLogs_createdAt, + connection_id: chunk.tableLogs_connectionIdId, + connection_title: chunk.connection_id_title, + table_name: chunk.tableLogs_table_name, + ...affectedPrimaryKey, + }; - callback(null, transformedChunk); - }, - }); + callback(null, transformedChunk); + }, + }); - const csvStream = csv.stringify({ header: true }); - logsAsStream.pipe(transformStream).pipe(csvStream); + const csvStream = csv.stringify({ header: true }); + logsAsStream.pipe(transformStream).pipe(csvStream); - return new StreamableFile(csvStream); - } + return new StreamableFile(csvStream); + } } diff --git a/backend/src/entities/table-logs/use-cases/find-logs.use.case.ts b/backend/src/entities/table-logs/use-cases/find-logs.use.case.ts index 45ace7b8a..9046f4583 100644 --- a/backend/src/entities/table-logs/use-cases/find-logs.use.case.ts +++ b/backend/src/entities/table-logs/use-cases/find-logs.use.case.ts @@ -14,111 +14,111 @@ import { IFindLogs } from './use-cases.interface.js'; @Injectable() export class FindLogsUseCase extends AbstractUseCase implements IFindLogs { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: FindLogsDs): Promise { - const { connectionId, query, userId, operationTypes } = inputData; - const userConnectionEdit = await this._dbContext.userAccessRepository.checkUserConnectionEdit(userId, connectionId); - const tableName = query.tableName; - let order = query.order; - let limit: string | number = query.limit; - let page = parseInt(query.page, 10); - let perPage: string | number = parseInt(query.perPage, 10); - const dateFrom = query.dateFrom; - const dateTo = query.dateTo; - const searchedEmail = query.email?.toLowerCase(); - const searchedAffectedPrimaryKey: string = query.affected_primary_key; - const operationType = query.operationType as LogOperationTypeEnum; - if (operationType) { - const actionValidationResult = validateStringWithEnum(operationType, LogOperationTypeEnum); - if (!actionValidationResult) { - throw new HttpException( - { - message: Messages.INCORRECT_TABLE_LOG_ACTION_TYPE, - }, - HttpStatus.BAD_REQUEST, - ); - } - } + protected async implementation(inputData: FindLogsDs): Promise { + const { connectionId, query, userId, operationTypes } = inputData; + const userConnectionEdit = await this._dbContext.userAccessRepository.checkUserConnectionEdit(userId, connectionId); + const tableName = query.tableName; + let order = query.order; + let limit: string | number = query.limit; + let page = parseInt(query.page, 10); + let perPage: string | number = parseInt(query.perPage, 10); + const dateFrom = query.dateFrom; + const dateTo = query.dateTo; + const searchedEmail = query.email?.toLowerCase(); + const searchedAffectedPrimaryKey: string = query.affected_primary_key; + const operationType = query.operationType as LogOperationTypeEnum; + if (operationType) { + const actionValidationResult = validateStringWithEnum(operationType, LogOperationTypeEnum); + if (!actionValidationResult) { + throw new HttpException( + { + message: Messages.INCORRECT_TABLE_LOG_ACTION_TYPE, + }, + HttpStatus.BAD_REQUEST, + ); + } + } - if (operationTypes.length > 0) { - for (const operationTypeElement of operationTypes) { - const actionValidationResult = validateStringWithEnum(operationTypeElement, LogOperationTypeEnum); - if (!actionValidationResult) { - throw new HttpException( - { - message: Messages.INCORRECT_TABLE_LOG_ACTION_TYPE, - }, - HttpStatus.BAD_REQUEST, - ); - } - } - } + if (operationTypes.length > 0) { + for (const operationTypeElement of operationTypes) { + const actionValidationResult = validateStringWithEnum(operationTypeElement, LogOperationTypeEnum); + if (!actionValidationResult) { + throw new HttpException( + { + message: Messages.INCORRECT_TABLE_LOG_ACTION_TYPE, + }, + HttpStatus.BAD_REQUEST, + ); + } + } + } - if (!order || order !== QueryOrderingEnum.ASC) { - order = QueryOrderingEnum.DESC; - } - if (!limit) { - limit = Constants.DEFAULT_LOG_ROWS_LIMIT; - } - if (!page || page <= 0) { - page = 1; - } - if (!perPage || perPage <= 0) { - perPage = limit; - } + if (!order || order !== QueryOrderingEnum.ASC) { + order = QueryOrderingEnum.DESC; + } + if (!limit) { + limit = Constants.DEFAULT_LOG_ROWS_LIMIT; + } + if (!page || page <= 0) { + page = 1; + } + if (!perPage || perPage <= 0) { + perPage = limit; + } - let searchedDateFrom: Date = null; - let searchedDateTo: Date = null; - if (dateFrom && dateTo) { - let dateFromParsed = Date.parse(dateFrom); - let dateToParsed = Date.parse(dateTo); - const dateFromMs = new Date(dateFromParsed).getTime(); - const dateToMs = new Date(dateToParsed).getTime(); - if (dateFromMs > dateToMs) { - const tmpDate = dateFromParsed; - dateFromParsed = dateToParsed; - dateToParsed = tmpDate; - } - searchedDateFrom = new Date(dateFromParsed); - searchedDateTo = new Date(dateToParsed); - } - let userIdsInGroupsWhereUserIsAdmin: Array = []; - if (!userConnectionEdit) { - const usersInGroupsWhereUserIsAdmin = await this._dbContext.groupRepository.findAllUsersInGroupsWhereUserIsAdmin( - userId, - connectionId, - ); - userIdsInGroupsWhereUserIsAdmin = usersInGroupsWhereUserIsAdmin.map((user) => user.id); - } + let searchedDateFrom: Date = null; + let searchedDateTo: Date = null; + if (dateFrom && dateTo) { + let dateFromParsed = Date.parse(dateFrom); + let dateToParsed = Date.parse(dateTo); + const dateFromMs = new Date(dateFromParsed).getTime(); + const dateToMs = new Date(dateToParsed).getTime(); + if (dateFromMs > dateToMs) { + const tmpDate = dateFromParsed; + dateFromParsed = dateToParsed; + dateToParsed = tmpDate; + } + searchedDateFrom = new Date(dateFromParsed); + searchedDateTo = new Date(dateToParsed); + } + let userIdsInGroupsWhereUserIsAdmin: Array = []; + if (!userConnectionEdit) { + const usersInGroupsWhereUserIsAdmin = await this._dbContext.groupRepository.findAllUsersInGroupsWhereUserIsAdmin( + userId, + connectionId, + ); + userIdsInGroupsWhereUserIsAdmin = usersInGroupsWhereUserIsAdmin.map((user) => user.id); + } - const findOptions: IFindLogsOptions = { - connectionId: connectionId, - currentUserId: userId, - dateFrom: searchedDateFrom, - dateTo: searchedDateTo, - order: order as QueryOrderingEnum, - page: page, - perPage: perPage as number, - searchedEmail: searchedEmail, - tableName: tableName ? tableName : null, - userConnectionEdit: userConnectionEdit, - userInGroupsIds: userIdsInGroupsWhereUserIsAdmin, - logOperationType: operationType, - logOperationTypes: operationTypes, - searchedAffectedPrimaryKey: searchedAffectedPrimaryKey, - }; - const { logs, pagination }: FoundLogsEntities = await this._dbContext.tableLogsRepository.findLogs(findOptions); - return { - logs: logs.map((log) => { - return buildFoundLogRecordDs(log); - }), - pagination: pagination, - }; - } + const findOptions: IFindLogsOptions = { + connectionId: connectionId, + currentUserId: userId, + dateFrom: searchedDateFrom, + dateTo: searchedDateTo, + order: order as QueryOrderingEnum, + page: page, + perPage: perPage as number, + searchedEmail: searchedEmail, + tableName: tableName ? tableName : null, + userConnectionEdit: userConnectionEdit, + userInGroupsIds: userIdsInGroupsWhereUserIsAdmin, + logOperationType: operationType, + logOperationTypes: operationTypes, + searchedAffectedPrimaryKey: searchedAffectedPrimaryKey, + }; + const { logs, pagination }: FoundLogsEntities = await this._dbContext.tableLogsRepository.findLogs(findOptions); + return { + logs: logs.map((log) => { + return buildFoundLogRecordDs(log); + }), + pagination: pagination, + }; + } } diff --git a/backend/src/entities/table-logs/use-cases/use-cases.interface.ts b/backend/src/entities/table-logs/use-cases/use-cases.interface.ts index dd24150b9..04b46aabc 100644 --- a/backend/src/entities/table-logs/use-cases/use-cases.interface.ts +++ b/backend/src/entities/table-logs/use-cases/use-cases.interface.ts @@ -1,12 +1,12 @@ -import { FoundLogsDs } from '../application/data-structures/found-logs.ds.js'; -import { FindLogsDs } from '../application/data-structures/find-logs.ds.js'; -import { InTransactionEnum } from '../../../enums/index.js'; import { StreamableFile } from '@nestjs/common'; +import { InTransactionEnum } from '../../../enums/index.js'; +import { FindLogsDs } from '../application/data-structures/find-logs.ds.js'; +import { FoundLogsDs } from '../application/data-structures/found-logs.ds.js'; export interface IFindLogs { - execute(inputData: FindLogsDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: FindLogsDs, inTransaction: InTransactionEnum): Promise; } export interface IExportLogsAsCsv { - execute(inputData: FindLogsDs): Promise; + execute(inputData: FindLogsDs): Promise; } diff --git a/backend/src/entities/table-logs/utils/build-created-log-record.ts b/backend/src/entities/table-logs/utils/build-created-log-record.ts index 1f868c5b5..895731c14 100644 --- a/backend/src/entities/table-logs/utils/build-created-log-record.ts +++ b/backend/src/entities/table-logs/utils/build-created-log-record.ts @@ -1,31 +1,31 @@ -import { TableLogsEntity } from '../table-logs.entity.js'; import { CreatedLogRecordDs } from '../application/data-structures/created-log-record.ds.js'; +import { TableLogsEntity } from '../table-logs.entity.js'; export function buildCreatedLogRecord(log: TableLogsEntity): CreatedLogRecordDs { - const { - cognitoUserName, - connection_id, - createdAt, - email, - id, - old_data, - operationStatusResult, - operationType, - received_data, - table_name, - affected_primary_key, - } = log; - return { - createdAt: createdAt, - email: email, - id: id, - old_data: old_data, - operationStatusResult: operationStatusResult, - operationType: operationType, - received_data: received_data, - table_name: table_name, - connection_id: connection_id as unknown as string, - userId: cognitoUserName, - affected_primary_key: affected_primary_key, - }; + const { + cognitoUserName, + connection_id, + createdAt, + email, + id, + old_data, + operationStatusResult, + operationType, + received_data, + table_name, + affected_primary_key, + } = log; + return { + createdAt: createdAt, + email: email, + id: id, + old_data: old_data, + operationStatusResult: operationStatusResult, + operationType: operationType, + received_data: received_data, + table_name: table_name, + connection_id: connection_id as unknown as string, + userId: cognitoUserName, + affected_primary_key: affected_primary_key, + }; } diff --git a/backend/src/entities/table-logs/utils/build-found-log-record-ds.ts b/backend/src/entities/table-logs/utils/build-found-log-record-ds.ts index ab306bef5..b6ee0dafb 100644 --- a/backend/src/entities/table-logs/utils/build-found-log-record-ds.ts +++ b/backend/src/entities/table-logs/utils/build-found-log-record-ds.ts @@ -2,29 +2,29 @@ import { FoundLogRecordDs } from '../application/data-structures/found-logs.ds.j import { TableLogsEntity } from '../table-logs.entity.js'; export function buildFoundLogRecordDs(log: TableLogsEntity): FoundLogRecordDs { - const { - cognitoUserName, - connection_id, - createdAt, - email, - old_data, - operationStatusResult, - operationType, - received_data, - table_name, - affected_primary_key, - } = log; - return { - table_name: table_name, - received_data: received_data, - old_data: old_data, - cognitoUserName: cognitoUserName, - email: email, - operationType: operationType, - operationStatusResult: operationStatusResult, - createdAt: createdAt, - connection_id: connection_id.id, - affected_primary_key: affected_primary_key, - operation_custom_action_name: log.operation_custom_action_name || null, - }; + const { + cognitoUserName, + connection_id, + createdAt, + email, + old_data, + operationStatusResult, + operationType, + received_data, + table_name, + affected_primary_key, + } = log; + return { + table_name: table_name, + received_data: received_data, + old_data: old_data, + cognitoUserName: cognitoUserName, + email: email, + operationType: operationType, + operationStatusResult: operationStatusResult, + createdAt: createdAt, + connection_id: connection_id.id, + affected_primary_key: affected_primary_key, + operation_custom_action_name: log.operation_custom_action_name || null, + }; } diff --git a/backend/src/entities/table-settings/application/data-structures/create-table-settings.ds.ts b/backend/src/entities/table-settings/application/data-structures/create-table-settings.ds.ts index 4743c25ed..3922b96d6 100644 --- a/backend/src/entities/table-settings/application/data-structures/create-table-settings.ds.ts +++ b/backend/src/entities/table-settings/application/data-structures/create-table-settings.ds.ts @@ -4,80 +4,80 @@ import { TableActionEntity } from '../../../table-actions/table-actions-module/t import { TableWidgetEntity } from '../../../widget/table-widget.entity.js'; export class CreateTableSettingsDs { - @ApiProperty({ isArray: true, type: 'string' }) - autocomplete_columns: Array; + @ApiProperty({ isArray: true, type: 'string' }) + autocomplete_columns: Array; - connection_id: string; + connection_id: string; - @ApiProperty({ isArray: true, required: false }) - custom_fields?: Array; + @ApiProperty({ isArray: true, required: false }) + custom_fields?: Array; - @ApiProperty() - display_name: string; + @ApiProperty() + display_name: string; - @ApiProperty({ isArray: true, type: 'string' }) - excluded_fields: Array; + @ApiProperty({ isArray: true, type: 'string' }) + excluded_fields: Array; - @ApiProperty({ isArray: true, type: 'string' }) - identification_fields: Array; + @ApiProperty({ isArray: true, type: 'string' }) + identification_fields: Array; - @ApiProperty() - identity_column: string; + @ApiProperty() + identity_column: string; - masterPwd: string; + masterPwd: string; - @ApiProperty({ isArray: true, type: 'string' }) - readonly_fields: Array; + @ApiProperty({ isArray: true, type: 'string' }) + readonly_fields: Array; - @ApiProperty({ isArray: true, type: 'string' }) - search_fields: Array; + @ApiProperty({ isArray: true, type: 'string' }) + search_fields: Array; - @ApiProperty({ isArray: true, type: 'string' }) - sortable_by: Array; + @ApiProperty({ isArray: true, type: 'string' }) + sortable_by: Array; - @ApiProperty({ isArray: true, type: 'string' }) - sensitive_fields: Array; + @ApiProperty({ isArray: true, type: 'string' }) + sensitive_fields: Array; - table_name: string; + table_name: string; - @ApiProperty({ isArray: true }) - table_widgets?: Array; + @ApiProperty({ isArray: true }) + table_widgets?: Array; - userId: string; + userId: string; - @ApiProperty({ isArray: true }) - table_actions?: Array; + @ApiProperty({ isArray: true }) + table_actions?: Array; - @ApiProperty() - can_delete: boolean; + @ApiProperty() + can_delete: boolean; - @ApiProperty() - can_update: boolean; + @ApiProperty() + can_update: boolean; - @ApiProperty() - can_add: boolean; + @ApiProperty() + can_add: boolean; - @ApiProperty() - icon: string; + @ApiProperty() + icon: string; - @ApiProperty() - allow_csv_export: boolean; + @ApiProperty() + allow_csv_export: boolean; - @ApiProperty() - allow_csv_import: boolean; + @ApiProperty() + allow_csv_import: boolean; - @ApiProperty({ required: false}) - list_per_page?: number; + @ApiProperty({ required: false }) + list_per_page?: number; - @ApiProperty({ isArray: true, type: 'string', required: false }) - list_fields?: Array; + @ApiProperty({ isArray: true, type: 'string', required: false }) + list_fields?: Array; - @ApiProperty({ required: false }) - ordering?: string; + @ApiProperty({ required: false }) + ordering?: string; - @ApiProperty({ required: false }) - ordering_field?: string; + @ApiProperty({ required: false }) + ordering_field?: string; - @ApiProperty({ isArray: true, type: 'string', required: false }) - columns_view?: Array; + @ApiProperty({ isArray: true, type: 'string', required: false }) + columns_view?: Array; } diff --git a/backend/src/entities/table-settings/application/data-structures/delete-table-settings.ds.ts b/backend/src/entities/table-settings/application/data-structures/delete-table-settings.ds.ts index ab47c6293..663abd6ed 100644 --- a/backend/src/entities/table-settings/application/data-structures/delete-table-settings.ds.ts +++ b/backend/src/entities/table-settings/application/data-structures/delete-table-settings.ds.ts @@ -1,4 +1,4 @@ export class DeleteTableSettingsDs { - connectionId: string; - tableName: string; + connectionId: string; + tableName: string; } diff --git a/backend/src/entities/table-settings/application/data-structures/find-table-settings.ds.ts b/backend/src/entities/table-settings/application/data-structures/find-table-settings.ds.ts index cdd33650e..40855cdd3 100644 --- a/backend/src/entities/table-settings/application/data-structures/find-table-settings.ds.ts +++ b/backend/src/entities/table-settings/application/data-structures/find-table-settings.ds.ts @@ -1,5 +1,5 @@ export class FindTableSettingsDs { - connectionId: string; - tableName: string; - masterPassword: string; + connectionId: string; + tableName: string; + masterPassword: string; } diff --git a/backend/src/entities/table-settings/common-table-settings/repository/table-settings-custom-repository-extension.ts b/backend/src/entities/table-settings/common-table-settings/repository/table-settings-custom-repository-extension.ts index ae590b827..77b3b9fb1 100644 --- a/backend/src/entities/table-settings/common-table-settings/repository/table-settings-custom-repository-extension.ts +++ b/backend/src/entities/table-settings/common-table-settings/repository/table-settings-custom-repository-extension.ts @@ -7,124 +7,124 @@ import { buildNewTableSettingsEntity } from '../utils/build-new-table-settings-e import { FoundTableSettingsData, ITableSettingsRepository } from './table-settings.repository.interface.js'; export const tableSettingsCustomRepositoryExtension: ITableSettingsRepository = { - async saveNewOrUpdatedSettings(settings: TableSettingsEntity): Promise { - return await this.save(settings); - }, + async saveNewOrUpdatedSettings(settings: TableSettingsEntity): Promise { + return await this.save(settings); + }, - async findTableCustoms(connectionId: string, tableName: string): Promise { - const qb = this.createQueryBuilder('tableSettings') - .leftJoinAndSelect('tableSettings.custom_fields', 'custom_fields') - .leftJoinAndSelect('tableSettings.table_widgets', 'table_widgets') - .where('tableSettings.connection_id = :connection_id', { - connection_id: connectionId, - }) - .andWhere('tableSettings.table_name = :table_name', { table_name: tableName }); + async findTableCustoms(connectionId: string, tableName: string): Promise { + const qb = this.createQueryBuilder('tableSettings') + .leftJoinAndSelect('tableSettings.custom_fields', 'custom_fields') + .leftJoinAndSelect('tableSettings.table_widgets', 'table_widgets') + .where('tableSettings.connection_id = :connection_id', { + connection_id: connectionId, + }) + .andWhere('tableSettings.table_name = :table_name', { table_name: tableName }); - const foundTableSettings = await qb.getOne(); - return { - tableSettings: foundTableSettings || null, - tableCustomFields: foundTableSettings ? foundTableSettings.custom_fields : [], - tableWidgets: foundTableSettings ? foundTableSettings.table_widgets : [], - }; - }, + const foundTableSettings = await qb.getOne(); + return { + tableSettings: foundTableSettings || null, + tableCustomFields: foundTableSettings ? foundTableSettings.custom_fields : [], + tableWidgets: foundTableSettings ? foundTableSettings.table_widgets : [], + }; + }, - async createNewTableSettings(settings: CreateTableSettingsDs): Promise { - const connectionQB = this.manager - .getRepository(ConnectionEntity) - .createQueryBuilder('connection') - .andWhere('connection.id = :connectionId', { - connectionId: settings.connection_id, - }); - const foundConnection = await connectionQB.getOne(); - const newTableSettings = buildNewTableSettingsEntity(settings, foundConnection); - return await this.save(newTableSettings); - }, + async createNewTableSettings(settings: CreateTableSettingsDs): Promise { + const connectionQB = this.manager + .getRepository(ConnectionEntity) + .createQueryBuilder('connection') + .andWhere('connection.id = :connectionId', { + connectionId: settings.connection_id, + }); + const foundConnection = await connectionQB.getOne(); + const newTableSettings = buildNewTableSettingsEntity(settings, foundConnection); + return await this.save(newTableSettings); + }, - async findTableSettingsWithCustomFields(connectionId: string, tableName: string): Promise { - const qb = this.createQueryBuilder('tableSettings').leftJoinAndSelect( - 'tableSettings.custom_fields', - 'custom_fields', - ); - qb.where('tableSettings.connection_id = :connection_id', { - connection_id: connectionId, - }); - qb.andWhere('tableSettings.table_name = :table_name', { - table_name: tableName, - }); - try { - return await qb.getOne(); - } catch (e) { - console.info(`Table setting not found exception. => `, e.message); - throw new HttpException( - { - message: Messages.TABLE_SETTINGS_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - }, + async findTableSettingsWithCustomFields(connectionId: string, tableName: string): Promise { + const qb = this.createQueryBuilder('tableSettings').leftJoinAndSelect( + 'tableSettings.custom_fields', + 'custom_fields', + ); + qb.where('tableSettings.connection_id = :connection_id', { + connection_id: connectionId, + }); + qb.andWhere('tableSettings.table_name = :table_name', { + table_name: tableName, + }); + try { + return await qb.getOne(); + } catch (e) { + console.info(`Table setting not found exception. => `, e.message); + throw new HttpException( + { + message: Messages.TABLE_SETTINGS_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + }, - async findTableSettings(connectionId: string, tableName: string): Promise { - const qb = this.createQueryBuilder('tableSettings').leftJoinAndSelect( - 'tableSettings.connection_id', - 'connection_id', - ); - qb.where('tableSettings.connection_id = :connection_id', { connection_id: connectionId }); - qb.andWhere('tableSettings.table_name = :table_name', { table_name: tableName }); - return await qb.getOne(); - }, + async findTableSettings(connectionId: string, tableName: string): Promise { + const qb = this.createQueryBuilder('tableSettings').leftJoinAndSelect( + 'tableSettings.connection_id', + 'connection_id', + ); + qb.where('tableSettings.connection_id = :connection_id', { connection_id: connectionId }); + qb.andWhere('tableSettings.table_name = :table_name', { table_name: tableName }); + return await qb.getOne(); + }, - async findTableSettingsPure(connectionId: string, tableName: string): Promise { - return await this.createQueryBuilder('tableSettings') - .leftJoin('tableSettings.connection_id', 'connection_id') - .where('tableSettings.connection_id = :connection_id', { connection_id: connectionId }) - .andWhere('tableSettings.table_name = :table_name', { table_name: tableName }) - .getOne(); - }, + async findTableSettingsPure(connectionId: string, tableName: string): Promise { + return await this.createQueryBuilder('tableSettings') + .leftJoin('tableSettings.connection_id', 'connection_id') + .where('tableSettings.connection_id = :connection_id', { connection_id: connectionId }) + .andWhere('tableSettings.table_name = :table_name', { table_name: tableName }) + .getOne(); + }, - //todo: remove after dao's and table settings refactor - async findTableSettingsOrReturnEmpty(connectionId: string, tableName: string): Promise { - const foundSettings = await this.findTableSettings(connectionId, tableName); - return foundSettings ? foundSettings : {}; - }, + //todo: remove after dao's and table settings refactor + async findTableSettingsOrReturnEmpty(connectionId: string, tableName: string): Promise { + const foundSettings = await this.findTableSettings(connectionId, tableName); + return foundSettings ? foundSettings : {}; + }, - async findTableSettingsInConnection(connectionId: string): Promise> { - const qb = this.createQueryBuilder('tableSettings').leftJoinAndSelect( - 'tableSettings.connection_id', - 'connection_id', - ); - qb.where('tableSettings.connection_id = :connection_id', { connection_id: connectionId }); - return await qb.getMany(); - }, + async findTableSettingsInConnection(connectionId: string): Promise> { + const qb = this.createQueryBuilder('tableSettings').leftJoinAndSelect( + 'tableSettings.connection_id', + 'connection_id', + ); + qb.where('tableSettings.connection_id = :connection_id', { connection_id: connectionId }); + return await qb.getMany(); + }, - async findTableSettingsInConnectionPure(connectionId: string): Promise> { - return await this.createQueryBuilder('tableSettings') - .leftJoin('tableSettings.connection_id', 'connection_id') - .where('tableSettings.connection_id = :connection_id', { connection_id: connectionId }) - .getMany(); - }, + async findTableSettingsInConnectionPure(connectionId: string): Promise> { + return await this.createQueryBuilder('tableSettings') + .leftJoin('tableSettings.connection_id', 'connection_id') + .where('tableSettings.connection_id = :connection_id', { connection_id: connectionId }) + .getMany(); + }, - async findTableSettingsWithTableWidgets(connectionId: string, tableName: string): Promise { - const qb = this.createQueryBuilder('tableSettings').leftJoinAndSelect( - 'tableSettings.table_widgets', - 'table_widgets', - ); - qb.where('tableSettings.connection_id = :connection_id', { connection_id: connectionId }); - qb.andWhere('tableSettings.table_name = :table_name', { table_name: tableName }); - return await qb.getOne(); - }, + async findTableSettingsWithTableWidgets(connectionId: string, tableName: string): Promise { + const qb = this.createQueryBuilder('tableSettings').leftJoinAndSelect( + 'tableSettings.table_widgets', + 'table_widgets', + ); + qb.where('tableSettings.connection_id = :connection_id', { connection_id: connectionId }); + qb.andWhere('tableSettings.table_name = :table_name', { table_name: tableName }); + return await qb.getOne(); + }, - async findTableSettingsWithTableActions(connectionId: string, tableName: string): Promise { - const qb = this.createQueryBuilder('tableSettings').leftJoinAndSelect( - 'tableSettings.table_actions', - 'table_actions', - ); - qb.where('tableSettings.connection_id = :connection_id', { connection_id: connectionId }); - qb.andWhere('tableSettings.table_name = :table_name', { table_name: tableName }); - return await qb.getOne(); - }, + async findTableSettingsWithTableActions(connectionId: string, tableName: string): Promise { + const qb = this.createQueryBuilder('tableSettings').leftJoinAndSelect( + 'tableSettings.table_actions', + 'table_actions', + ); + qb.where('tableSettings.connection_id = :connection_id', { connection_id: connectionId }); + qb.andWhere('tableSettings.table_name = :table_name', { table_name: tableName }); + return await qb.getOne(); + }, - async removeTableSettings(tableSettings: TableSettingsEntity): Promise { - return await this.remove(tableSettings); - }, + async removeTableSettings(tableSettings: TableSettingsEntity): Promise { + return await this.remove(tableSettings); + }, }; diff --git a/backend/src/entities/table-settings/common-table-settings/repository/table-settings.repository.interface.ts b/backend/src/entities/table-settings/common-table-settings/repository/table-settings.repository.interface.ts index 86639828d..a9aa66af1 100644 --- a/backend/src/entities/table-settings/common-table-settings/repository/table-settings.repository.interface.ts +++ b/backend/src/entities/table-settings/common-table-settings/repository/table-settings.repository.interface.ts @@ -4,32 +4,32 @@ import { CreateTableSettingsDs } from '../../application/data-structures/create- import { TableSettingsEntity } from '../table-settings.entity.js'; export type FoundTableSettingsData = { - tableSettings: TableSettingsEntity; - tableCustomFields: Array; - tableWidgets: Array; + tableSettings: TableSettingsEntity; + tableCustomFields: Array; + tableWidgets: Array; }; export interface ITableSettingsRepository { - findTableCustoms(connectionId: string, tableName: string): Promise; + findTableCustoms(connectionId: string, tableName: string): Promise; - saveNewOrUpdatedSettings(settings: TableSettingsEntity): Promise; + saveNewOrUpdatedSettings(settings: TableSettingsEntity): Promise; - findTableSettingsWithCustomFields(connectionId: string, tableName: string): Promise; + findTableSettingsWithCustomFields(connectionId: string, tableName: string): Promise; - createNewTableSettings(settings: CreateTableSettingsDs): Promise; + createNewTableSettings(settings: CreateTableSettingsDs): Promise; - findTableSettings(connectionId: string, tableName: string): Promise; + findTableSettings(connectionId: string, tableName: string): Promise; - findTableSettingsPure(connectionId: string, tableName: string): Promise; + findTableSettingsPure(connectionId: string, tableName: string): Promise; - findTableSettingsInConnectionPure(connectionId: string): Promise>; + findTableSettingsInConnectionPure(connectionId: string): Promise>; - findTableSettingsOrReturnEmpty(connectionId: string, tableName: string): Promise; + findTableSettingsOrReturnEmpty(connectionId: string, tableName: string): Promise; - removeTableSettings(tableSettings: TableSettingsEntity): Promise; + removeTableSettings(tableSettings: TableSettingsEntity): Promise; - findTableSettingsInConnection(connectionId: string): Promise>; + findTableSettingsInConnection(connectionId: string): Promise>; - findTableSettingsWithTableWidgets(connectionId: string, tableName: string): Promise; + findTableSettingsWithTableWidgets(connectionId: string, tableName: string): Promise; - findTableSettingsWithTableActions(connectionId: string, tableName: string): Promise; + findTableSettingsWithTableActions(connectionId: string, tableName: string): Promise; } diff --git a/backend/src/entities/table-settings/common-table-settings/table-settings.controller.ts b/backend/src/entities/table-settings/common-table-settings/table-settings.controller.ts index a4fb7cd08..2e747f285 100644 --- a/backend/src/entities/table-settings/common-table-settings/table-settings.controller.ts +++ b/backend/src/entities/table-settings/common-table-settings/table-settings.controller.ts @@ -16,6 +16,7 @@ import { HttpException } from '@nestjs/common/exceptions/http.exception.js'; import { ApiBearerAuth, ApiBody, ApiOperation, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger'; import { UseCaseType } from '../../../common/data-injection.tokens.js'; import { MasterPassword, QueryTableName, QueryUuid, UserId } from '../../../decorators/index.js'; +import { Timeout } from '../../../decorators/timeout.decorator.js'; import { InTransactionEnum } from '../../../enums/index.js'; import { Messages } from '../../../exceptions/text/messages.js'; import { ConnectionEditGuard, ConnectionReadGuard } from '../../../guards/index.js'; @@ -33,7 +34,6 @@ import { IFindTableSettings, IUpdateTableSettings, } from './use-cases/use-cases.interface.js'; -import { Timeout } from '../../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/table-settings/common-table-settings/table-settings.module.ts b/backend/src/entities/table-settings/common-table-settings/table-settings.module.ts index 854451731..d76a50416 100644 --- a/backend/src/entities/table-settings/common-table-settings/table-settings.module.ts +++ b/backend/src/entities/table-settings/common-table-settings/table-settings.module.ts @@ -4,8 +4,8 @@ import { AuthMiddleware } from '../../../authorization/index.js'; import { GlobalDatabaseContext } from '../../../common/application/global-database-context.js'; import { BaseType, UseCaseType } from '../../../common/data-injection.tokens.js'; import { AgentModule } from '../../agent/agent.module.js'; -import { ConnectionPropertiesEntity } from '../../connection-properties/connection-properties.entity.js'; import { ConnectionEntity } from '../../connection/connection.entity.js'; +import { ConnectionPropertiesEntity } from '../../connection-properties/connection-properties.entity.js'; import { CustomFieldsEntity } from '../../custom-field/custom-fields.entity.js'; import { GroupEntity } from '../../group/group.entity.js'; import { LogOutEntity } from '../../log-out/log-out.entity.js'; @@ -22,56 +22,56 @@ import { FindTableSettingsUseCase } from './use-cases/find-table-settings.use.ca import { UpdateTableSettingsUseCase } from './use-cases/update-table-settings.use.case.js'; @Module({ - imports: [ - TypeOrmModule.forFeature([ - ConnectionEntity, - CustomFieldsEntity, - GroupEntity, - PermissionEntity, - TableLogsEntity, - TableSettingsEntity, - TableWidgetEntity, - UserEntity, - ConnectionPropertiesEntity, - LogOutEntity, - ]), - AgentModule, - UserModule, - ], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.FIND_TABLE_SETTINGS, - useClass: FindTableSettingsUseCase, - }, - { - provide: UseCaseType.CREATE_TABLE_SETTINGS, - useClass: CreateTableSettingsUseCase, - }, - { - provide: UseCaseType.UPDATE_TABLE_SETTINGS, - useClass: UpdateTableSettingsUseCase, - }, - { - provide: UseCaseType.DELETE_TABLE_SETTINGS, - useClass: DeleteTableSettingsUseCase, - }, - ], - controllers: [TableSettingsController], - exports: [], + imports: [ + TypeOrmModule.forFeature([ + ConnectionEntity, + CustomFieldsEntity, + GroupEntity, + PermissionEntity, + TableLogsEntity, + TableSettingsEntity, + TableWidgetEntity, + UserEntity, + ConnectionPropertiesEntity, + LogOutEntity, + ]), + AgentModule, + UserModule, + ], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.FIND_TABLE_SETTINGS, + useClass: FindTableSettingsUseCase, + }, + { + provide: UseCaseType.CREATE_TABLE_SETTINGS, + useClass: CreateTableSettingsUseCase, + }, + { + provide: UseCaseType.UPDATE_TABLE_SETTINGS, + useClass: UpdateTableSettingsUseCase, + }, + { + provide: UseCaseType.DELETE_TABLE_SETTINGS, + useClass: DeleteTableSettingsUseCase, + }, + ], + controllers: [TableSettingsController], + exports: [], }) export class TableSettingsModule { - public configure(consumer: MiddlewareConsumer): any { - consumer - .apply(AuthMiddleware) - .forRoutes( - { path: '/settings/', method: RequestMethod.GET }, - { path: '/settings/', method: RequestMethod.POST }, - { path: '/settings/', method: RequestMethod.PUT }, - { path: '/settings/', method: RequestMethod.DELETE }, - ); - } + public configure(consumer: MiddlewareConsumer): any { + consumer + .apply(AuthMiddleware) + .forRoutes( + { path: '/settings/', method: RequestMethod.GET }, + { path: '/settings/', method: RequestMethod.POST }, + { path: '/settings/', method: RequestMethod.PUT }, + { path: '/settings/', method: RequestMethod.DELETE }, + ); + } } diff --git a/backend/src/entities/table-settings/common-table-settings/use-cases/create-table-settings.use.case.ts b/backend/src/entities/table-settings/common-table-settings/use-cases/create-table-settings.use.case.ts index bb16590f5..91cdee2c9 100644 --- a/backend/src/entities/table-settings/common-table-settings/use-cases/create-table-settings.use.case.ts +++ b/backend/src/entities/table-settings/common-table-settings/use-cases/create-table-settings.use.case.ts @@ -1,59 +1,59 @@ import { HttpStatus, Inject, Injectable, Scope } from '@nestjs/common'; import { HttpException } from '@nestjs/common/exceptions/http.exception.js'; +import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; +import { ValidateTableSettingsDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/validate-table-settings.ds.js'; +import { buildValidateTableSettingsDS } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/validate-table-settings-ds.builder.js'; import AbstractUseCase from '../../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../../common/data-injection.tokens.js'; -import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import { toPrettyErrorsMsg } from '../../../../helpers/index.js'; import { CreateTableSettingsDs } from '../../application/data-structures/create-table-settings.ds.js'; import { FoundTableSettingsDs } from '../../application/data-structures/found-table-settings.ds.js'; import { buildFoundTableSettingsDs } from '../utils/build-found-table-settings-ds.js'; import { buildNewTableSettingsEntity } from '../utils/build-new-table-settings-entity.js'; import { ICreateTableSettings } from './use-cases.interface.js'; -import { ValidateTableSettingsDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/validate-table-settings.ds.js'; -import { buildValidateTableSettingsDS } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/validate-table-settings-ds.builder.js'; @Injectable({ scope: Scope.REQUEST }) export class CreateTableSettingsUseCase - extends AbstractUseCase - implements ICreateTableSettings + extends AbstractUseCase + implements ICreateTableSettings { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: CreateTableSettingsDs): Promise { - const { connection_id, masterPwd, table_name } = inputData; - const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( - connection_id, - masterPwd, - ); - const dao = getDataAccessObject(foundConnection); - const tableSettingsDs: ValidateTableSettingsDS = buildValidateTableSettingsDS(inputData); - const errors: Array = await dao.validateSettings(tableSettingsDs, table_name, undefined); - if (errors.length > 0) { - throw new HttpException( - { - message: toPrettyErrorsMsg(errors), - }, - HttpStatus.BAD_REQUEST, - ); - } - const newTableSettingEntity = buildNewTableSettingsEntity(inputData, foundConnection); + protected async implementation(inputData: CreateTableSettingsDs): Promise { + const { connection_id, masterPwd, table_name } = inputData; + const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( + connection_id, + masterPwd, + ); + const dao = getDataAccessObject(foundConnection); + const tableSettingsDs: ValidateTableSettingsDS = buildValidateTableSettingsDS(inputData); + const errors: Array = await dao.validateSettings(tableSettingsDs, table_name, undefined); + if (errors.length > 0) { + throw new HttpException( + { + message: toPrettyErrorsMsg(errors), + }, + HttpStatus.BAD_REQUEST, + ); + } + const newTableSettingEntity = buildNewTableSettingsEntity(inputData, foundConnection); - const foundTableSettings = await this._dbContext.tableSettingsRepository.findTableSettings( - connection_id, - table_name, - ); - if (foundTableSettings) { - await this._dbContext.tableSettingsRepository.remove(foundTableSettings); - } + const foundTableSettings = await this._dbContext.tableSettingsRepository.findTableSettings( + connection_id, + table_name, + ); + if (foundTableSettings) { + await this._dbContext.tableSettingsRepository.remove(foundTableSettings); + } - const savedTableSettings = - await this._dbContext.tableSettingsRepository.saveNewOrUpdatedSettings(newTableSettingEntity); - return buildFoundTableSettingsDs(savedTableSettings); - } + const savedTableSettings = + await this._dbContext.tableSettingsRepository.saveNewOrUpdatedSettings(newTableSettingEntity); + return buildFoundTableSettingsDs(savedTableSettings); + } } diff --git a/backend/src/entities/table-settings/common-table-settings/use-cases/delete-table-settings.use.case.ts b/backend/src/entities/table-settings/common-table-settings/use-cases/delete-table-settings.use.case.ts index cde7f1020..4e1be687f 100644 --- a/backend/src/entities/table-settings/common-table-settings/use-cases/delete-table-settings.use.case.ts +++ b/backend/src/entities/table-settings/common-table-settings/use-cases/delete-table-settings.use.case.ts @@ -10,31 +10,31 @@ import { IDeleteTableSettings } from './use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class DeleteTableSettingsUseCase - extends AbstractUseCase - implements IDeleteTableSettings + extends AbstractUseCase + implements IDeleteTableSettings { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: DeleteTableSettingsDs): Promise { - const { connectionId, tableName } = inputData; - const tableSettingsToDelete = await this._dbContext.tableSettingsRepository.findTableSettings( - connectionId, - tableName, - ); - if (!tableSettingsToDelete) { - throw new HttpException( - { - message: Messages.TABLE_SETTINGS_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - const deletedSettings = await this._dbContext.tableSettingsRepository.removeTableSettings(tableSettingsToDelete); - return buildFoundTableSettingsDs(deletedSettings); - } + protected async implementation(inputData: DeleteTableSettingsDs): Promise { + const { connectionId, tableName } = inputData; + const tableSettingsToDelete = await this._dbContext.tableSettingsRepository.findTableSettings( + connectionId, + tableName, + ); + if (!tableSettingsToDelete) { + throw new HttpException( + { + message: Messages.TABLE_SETTINGS_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + const deletedSettings = await this._dbContext.tableSettingsRepository.removeTableSettings(tableSettingsToDelete); + return buildFoundTableSettingsDs(deletedSettings); + } } diff --git a/backend/src/entities/table-settings/common-table-settings/use-cases/find-table-settings.use.case.ts b/backend/src/entities/table-settings/common-table-settings/use-cases/find-table-settings.use.case.ts index c1d9e97e6..c1c423830 100644 --- a/backend/src/entities/table-settings/common-table-settings/use-cases/find-table-settings.use.case.ts +++ b/backend/src/entities/table-settings/common-table-settings/use-cases/find-table-settings.use.case.ts @@ -10,30 +10,30 @@ import { IFindTableSettings } from './use-cases.interface.js'; @Injectable() export class FindTableSettingsUseCase - extends AbstractUseCase - implements IFindTableSettings + extends AbstractUseCase + implements IFindTableSettings { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } - protected async implementation(inputData: FindTableSettingsDs): Promise { - const { connectionId, tableName, masterPassword } = inputData; - const tableSettings = await this._dbContext.tableSettingsRepository.findTableSettings(connectionId, tableName); - if (!tableSettings) { - return {} as FoundTableSettingsDs; - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } + protected async implementation(inputData: FindTableSettingsDs): Promise { + const { connectionId, tableName, masterPassword } = inputData; + const tableSettings = await this._dbContext.tableSettingsRepository.findTableSettings(connectionId, tableName); + if (!tableSettings) { + return {} as FoundTableSettingsDs; + } - const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( - connectionId, - masterPassword, - ); - if (!foundConnection) { - throw new NotFoundException(Messages.CONNECTION_NOT_FOUND); - } + const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( + connectionId, + masterPassword, + ); + if (!foundConnection) { + throw new NotFoundException(Messages.CONNECTION_NOT_FOUND); + } - return buildFoundTableSettingsDs(tableSettings); - } + return buildFoundTableSettingsDs(tableSettings); + } } diff --git a/backend/src/entities/table-settings/common-table-settings/use-cases/update-table-settings.use.case.ts b/backend/src/entities/table-settings/common-table-settings/use-cases/update-table-settings.use.case.ts index 6d6410895..2c50d303d 100644 --- a/backend/src/entities/table-settings/common-table-settings/use-cases/update-table-settings.use.case.ts +++ b/backend/src/entities/table-settings/common-table-settings/use-cases/update-table-settings.use.case.ts @@ -1,9 +1,11 @@ import { HttpStatus, Inject, Injectable, Scope } from '@nestjs/common'; import { HttpException } from '@nestjs/common/exceptions/http.exception.js'; +import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; +import { ValidateTableSettingsDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/validate-table-settings.ds.js'; +import { buildValidateTableSettingsDS } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/validate-table-settings-ds.builder.js'; import AbstractUseCase from '../../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../../common/data-injection.tokens.js'; -import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import { Messages } from '../../../../exceptions/text/messages.js'; import { toPrettyErrorsMsg } from '../../../../helpers/index.js'; import { CreateTableSettingsDs } from '../../application/data-structures/create-table-settings.ds.js'; @@ -11,8 +13,6 @@ import { FoundTableSettingsDs } from '../../application/data-structures/found-ta import { buildFoundTableSettingsDs } from '../utils/build-found-table-settings-ds.js'; import { buildNewTableSettingsEntity } from '../utils/build-new-table-settings-entity.js'; import { IUpdateTableSettings } from './use-cases.interface.js'; -import { ValidateTableSettingsDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/validate-table-settings.ds.js'; -import { buildValidateTableSettingsDS } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/validate-table-settings-ds.builder.js'; @Injectable({ scope: Scope.REQUEST }) export class UpdateTableSettingsUseCase diff --git a/backend/src/entities/table-settings/common-table-settings/use-cases/use-cases.interface.ts b/backend/src/entities/table-settings/common-table-settings/use-cases/use-cases.interface.ts index 7c43f68b5..46c1c4e0d 100644 --- a/backend/src/entities/table-settings/common-table-settings/use-cases/use-cases.interface.ts +++ b/backend/src/entities/table-settings/common-table-settings/use-cases/use-cases.interface.ts @@ -5,17 +5,17 @@ import { FindTableSettingsDs } from '../../application/data-structures/find-tabl import { FoundTableSettingsDs } from '../../application/data-structures/found-table-settings.ds.js'; export interface IFindTableSettings { - execute(inputData: FindTableSettingsDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: FindTableSettingsDs, inTransaction: InTransactionEnum): Promise; } export interface ICreateTableSettings { - execute(inputData: CreateTableSettingsDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: CreateTableSettingsDs, inTransaction: InTransactionEnum): Promise; } export interface IUpdateTableSettings { - execute(inputData: CreateTableSettingsDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: CreateTableSettingsDs, inTransaction: InTransactionEnum): Promise; } export interface IDeleteTableSettings { - execute(inputData: DeleteTableSettingsDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: DeleteTableSettingsDs, inTransaction: InTransactionEnum): Promise; } diff --git a/backend/src/entities/table-settings/common-table-settings/utils/build-new-table-settings-entity.ts b/backend/src/entities/table-settings/common-table-settings/utils/build-new-table-settings-entity.ts index 85536deeb..19ffe5ec1 100644 --- a/backend/src/entities/table-settings/common-table-settings/utils/build-new-table-settings-entity.ts +++ b/backend/src/entities/table-settings/common-table-settings/utils/build-new-table-settings-entity.ts @@ -1,7 +1,7 @@ +import { QueryOrderingEnum } from '../../../../enums/query-ordering.enum.js'; import { ConnectionEntity } from '../../../connection/connection.entity.js'; import { CreateTableSettingsDs } from '../../application/data-structures/create-table-settings.ds.js'; import { TableSettingsEntity } from '../table-settings.entity.js'; -import { QueryOrderingEnum } from '../../../../enums/query-ordering.enum.js'; export function buildNewTableSettingsEntity( settings: CreateTableSettingsDs, diff --git a/backend/src/entities/table-settings/personal-table-settings/data-structures/create-personal-table-settings.ds.ts b/backend/src/entities/table-settings/personal-table-settings/data-structures/create-personal-table-settings.ds.ts index 884f5bd9e..3d55360a4 100644 --- a/backend/src/entities/table-settings/personal-table-settings/data-structures/create-personal-table-settings.ds.ts +++ b/backend/src/entities/table-settings/personal-table-settings/data-structures/create-personal-table-settings.ds.ts @@ -1,22 +1,22 @@ import { QueryOrderingEnum } from '../../../../enums/query-ordering.enum.js'; export type PersonalTableSettingsMetadata = { - connection_id: string; - table_name: string; - user_id: string; - master_password: string; + connection_id: string; + table_name: string; + user_id: string; + master_password: string; }; export type PersonalTableSettingsData = { - ordering: QueryOrderingEnum | null; - ordering_field: string | null; - list_per_page: number | null; - columns_view: Array | null; - list_fields: Array | null; - original_names: boolean | null; + ordering: QueryOrderingEnum | null; + ordering_field: string | null; + list_per_page: number | null; + columns_view: Array | null; + list_fields: Array | null; + original_names: boolean | null; }; export class CreatePersonalTableSettingsDs { - table_settings_metadata: PersonalTableSettingsMetadata; - table_settings_data: PersonalTableSettingsData; + table_settings_metadata: PersonalTableSettingsMetadata; + table_settings_data: PersonalTableSettingsData; } diff --git a/backend/src/entities/table-settings/personal-table-settings/data-structures/find-personal-table-settings.ds.ts b/backend/src/entities/table-settings/personal-table-settings/data-structures/find-personal-table-settings.ds.ts index aefcf5c3c..ab551a34c 100644 --- a/backend/src/entities/table-settings/personal-table-settings/data-structures/find-personal-table-settings.ds.ts +++ b/backend/src/entities/table-settings/personal-table-settings/data-structures/find-personal-table-settings.ds.ts @@ -1,6 +1,6 @@ export class FindPersonalTableSettingsDs { - connectionId: string; - userId: string; - tableName: string; - masterPassword: string; + connectionId: string; + userId: string; + tableName: string; + masterPassword: string; } diff --git a/backend/src/entities/table-settings/personal-table-settings/dto/create-personal-table-settings.dto.ts b/backend/src/entities/table-settings/personal-table-settings/dto/create-personal-table-settings.dto.ts index f2a962f40..1ba4bda9d 100644 --- a/backend/src/entities/table-settings/personal-table-settings/dto/create-personal-table-settings.dto.ts +++ b/backend/src/entities/table-settings/personal-table-settings/dto/create-personal-table-settings.dto.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; -import { QueryOrderingEnum } from '../../../../enums/query-ordering.enum.js'; import { IsBoolean, IsEnum, IsOptional } from 'class-validator'; +import { QueryOrderingEnum } from '../../../../enums/query-ordering.enum.js'; export class CreatePersonalTableSettingsDto { @ApiProperty({ enumName: 'QueryOrderingEnum', enum: QueryOrderingEnum, description: 'The ordering direction' }) diff --git a/backend/src/entities/table-settings/personal-table-settings/dto/found-personal-table-settings.dto.ts b/backend/src/entities/table-settings/personal-table-settings/dto/found-personal-table-settings.dto.ts index 5d997b68e..f45149272 100644 --- a/backend/src/entities/table-settings/personal-table-settings/dto/found-personal-table-settings.dto.ts +++ b/backend/src/entities/table-settings/personal-table-settings/dto/found-personal-table-settings.dto.ts @@ -2,27 +2,27 @@ import { ApiProperty } from '@nestjs/swagger'; import { QueryOrderingEnum } from '../../../../enums/query-ordering.enum.js'; export class FoundPersonalTableSettingsDto { - @ApiProperty({ type: String, description: 'The entity id' }) - id: string; + @ApiProperty({ type: String, description: 'The entity id' }) + id: string; - @ApiProperty({ type: String, description: 'The table name' }) - table_name: string; + @ApiProperty({ type: String, description: 'The table name' }) + table_name: string; - @ApiProperty({ type: String, enum: ['ASC', 'DESC'], description: 'The ordering direction' }) - ordering: QueryOrderingEnum; + @ApiProperty({ type: String, enum: ['ASC', 'DESC'], description: 'The ordering direction' }) + ordering: QueryOrderingEnum; - @ApiProperty({ type: String, description: 'The ordering field' }) - ordering_field: string; + @ApiProperty({ type: String, description: 'The ordering field' }) + ordering_field: string; - @ApiProperty({ type: Number, description: 'The number of items per page' }) - list_per_page: number; + @ApiProperty({ type: Number, description: 'The number of items per page' }) + list_per_page: number; - @ApiProperty({ isArray: true, type: String, description: 'The columns view' }) - columns_view: Array; + @ApiProperty({ isArray: true, type: String, description: 'The columns view' }) + columns_view: Array; - @ApiProperty({ type: [String], description: 'The order of columns' }) - list_fields: Array; + @ApiProperty({ type: [String], description: 'The order of columns' }) + list_fields: Array; - @ApiProperty({ type: Boolean, description: 'Whether to use original column names' }) - original_names: boolean; + @ApiProperty({ type: Boolean, description: 'Whether to use original column names' }) + original_names: boolean; } diff --git a/backend/src/entities/table-settings/personal-table-settings/personal-table-settings.controller.ts b/backend/src/entities/table-settings/personal-table-settings/personal-table-settings.controller.ts index ca753a8c6..8797c5585 100644 --- a/backend/src/entities/table-settings/personal-table-settings/personal-table-settings.controller.ts +++ b/backend/src/entities/table-settings/personal-table-settings/personal-table-settings.controller.ts @@ -12,25 +12,25 @@ import { UseInterceptors, } from '@nestjs/common'; import { ApiBearerAuth, ApiBody, ApiOperation, ApiParam, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger'; -import { SentryInterceptor } from '../../../interceptors/sentry.interceptor.js'; import { UseCaseType } from '../../../common/data-injection.tokens.js'; +import { MasterPassword } from '../../../decorators/master-password.decorator.js'; +import { QueryTableName } from '../../../decorators/query-table-name.decorator.js'; +import { SlugUuid } from '../../../decorators/slug-uuid.decorator.js'; +import { Timeout } from '../../../decorators/timeout.decorator.js'; +import { UserId } from '../../../decorators/user-id.decorator.js'; +import { InTransactionEnum } from '../../../enums/in-transaction.enum.js'; +import { Messages } from '../../../exceptions/text/messages.js'; +import { TableReadGuard } from '../../../guards/table-read.guard.js'; +import { SentryInterceptor } from '../../../interceptors/sentry.interceptor.js'; +import { CreatePersonalTableSettingsDs } from './data-structures/create-personal-table-settings.ds.js'; +import { FindPersonalTableSettingsDs } from './data-structures/find-personal-table-settings.ds.js'; +import { CreatePersonalTableSettingsDto } from './dto/create-personal-table-settings.dto.js'; +import { FoundPersonalTableSettingsDto } from './dto/found-personal-table-settings.dto.js'; import { ICreateUpdatePersonalTableSettings, IDeletePersonalTableSettings, IFindPersonalTableSettings, } from './use-cases/personal-table-settings.use-cases.interface.js'; -import { TableReadGuard } from '../../../guards/table-read.guard.js'; -import { UserId } from '../../../decorators/user-id.decorator.js'; -import { QueryTableName } from '../../../decorators/query-table-name.decorator.js'; -import { MasterPassword } from '../../../decorators/master-password.decorator.js'; -import { Messages } from '../../../exceptions/text/messages.js'; -import { InTransactionEnum } from '../../../enums/in-transaction.enum.js'; -import { FindPersonalTableSettingsDs } from './data-structures/find-personal-table-settings.ds.js'; -import { FoundPersonalTableSettingsDto } from './dto/found-personal-table-settings.dto.js'; -import { SlugUuid } from '../../../decorators/slug-uuid.decorator.js'; -import { CreatePersonalTableSettingsDs } from './data-structures/create-personal-table-settings.ds.js'; -import { CreatePersonalTableSettingsDto } from './dto/create-personal-table-settings.dto.js'; -import { Timeout } from '../../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/table-settings/personal-table-settings/personal-table-settings.module.ts b/backend/src/entities/table-settings/personal-table-settings/personal-table-settings.module.ts index 4ee488227..0fc53f8ff 100644 --- a/backend/src/entities/table-settings/personal-table-settings/personal-table-settings.module.ts +++ b/backend/src/entities/table-settings/personal-table-settings/personal-table-settings.module.ts @@ -1,45 +1,45 @@ import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'; -import { GlobalDatabaseContext } from '../../../common/application/global-database-context.js'; -import { BaseType, UseCaseType } from '../../../common/data-injection.tokens.js'; -import { FindPersonalTableSettingsUseCase } from './use-cases/find-personal-table-settings.use.case.js'; -import { CreateUpdatePersonalTableSettingsUseCase } from './use-cases/create-update-personal-table-settings.use.case.js'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { PersonalTableSettingsController } from './personal-table-settings.controller.js'; import { AuthMiddleware } from '../../../authorization/auth.middleware.js'; -import { UserEntity } from '../../user/user.entity.js'; +import { GlobalDatabaseContext } from '../../../common/application/global-database-context.js'; +import { BaseType, UseCaseType } from '../../../common/data-injection.tokens.js'; import { LogOutEntity } from '../../log-out/log-out.entity.js'; +import { UserEntity } from '../../user/user.entity.js'; +import { PersonalTableSettingsController } from './personal-table-settings.controller.js'; +import { CreateUpdatePersonalTableSettingsUseCase } from './use-cases/create-update-personal-table-settings.use.case.js'; +import { FindPersonalTableSettingsUseCase } from './use-cases/find-personal-table-settings.use.case.js'; @Module({ - imports: [TypeOrmModule.forFeature([UserEntity, LogOutEntity])], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.FIND_PERSONAL_TABLE_SETTINGS, - useClass: FindPersonalTableSettingsUseCase, - }, - { - provide: UseCaseType.CREATE_UPDATE_PERSONAL_TABLE_SETTINGS, - useClass: CreateUpdatePersonalTableSettingsUseCase, - }, - { - provide: UseCaseType.DELETE_PERSONAL_TABLE_SETTINGS, - useClass: CreateUpdatePersonalTableSettingsUseCase, - }, - ], - controllers: [PersonalTableSettingsController], - exports: [], + imports: [TypeOrmModule.forFeature([UserEntity, LogOutEntity])], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.FIND_PERSONAL_TABLE_SETTINGS, + useClass: FindPersonalTableSettingsUseCase, + }, + { + provide: UseCaseType.CREATE_UPDATE_PERSONAL_TABLE_SETTINGS, + useClass: CreateUpdatePersonalTableSettingsUseCase, + }, + { + provide: UseCaseType.DELETE_PERSONAL_TABLE_SETTINGS, + useClass: CreateUpdatePersonalTableSettingsUseCase, + }, + ], + controllers: [PersonalTableSettingsController], + exports: [], }) export class PersonalTableSettingsModule { - public configure(consumer: MiddlewareConsumer): any { - consumer - .apply(AuthMiddleware) - .forRoutes( - { path: '/settings/personal/:connectionId', method: RequestMethod.GET }, - { path: '/settings/personal/:connectionId', method: RequestMethod.PUT }, - { path: '/settings/personal/:connectionId', method: RequestMethod.DELETE }, - ); - } + public configure(consumer: MiddlewareConsumer): any { + consumer + .apply(AuthMiddleware) + .forRoutes( + { path: '/settings/personal/:connectionId', method: RequestMethod.GET }, + { path: '/settings/personal/:connectionId', method: RequestMethod.PUT }, + { path: '/settings/personal/:connectionId', method: RequestMethod.DELETE }, + ); + } } diff --git a/backend/src/entities/table-settings/personal-table-settings/repository/personal-table-settings-custom-repository-extension.ts b/backend/src/entities/table-settings/personal-table-settings/repository/personal-table-settings-custom-repository-extension.ts index cfd4f1d97..a3c669fe8 100644 --- a/backend/src/entities/table-settings/personal-table-settings/repository/personal-table-settings-custom-repository-extension.ts +++ b/backend/src/entities/table-settings/personal-table-settings/repository/personal-table-settings-custom-repository-extension.ts @@ -2,21 +2,21 @@ import { PersonalTableSettingsEntity } from '../personal-table-settings.entity.j import { IPersonalTableSettingsRepository } from './personal-table-settings.repository.interface.js'; export const personalTableSettingsCustomRepositoryExtension: IPersonalTableSettingsRepository = { - async findUserTableSettings( - userId: string, - connectionId: string, - tableName: string, - ): Promise { - const qb = this.createQueryBuilder('personal_table_settings'); - qb.where('personal_table_settings.user_id = :userId', { - userId, - }); - qb.andWhere('personal_table_settings.connection_id = :connectionId', { - connectionId, - }); - qb.andWhere('personal_table_settings.table_name = :tableName', { - tableName, - }); - return await qb.getOne(); - }, + async findUserTableSettings( + userId: string, + connectionId: string, + tableName: string, + ): Promise { + const qb = this.createQueryBuilder('personal_table_settings'); + qb.where('personal_table_settings.user_id = :userId', { + userId, + }); + qb.andWhere('personal_table_settings.connection_id = :connectionId', { + connectionId, + }); + qb.andWhere('personal_table_settings.table_name = :tableName', { + tableName, + }); + return await qb.getOne(); + }, }; diff --git a/backend/src/entities/table-settings/personal-table-settings/repository/personal-table-settings.repository.interface.ts b/backend/src/entities/table-settings/personal-table-settings/repository/personal-table-settings.repository.interface.ts index 2920239bb..31b604507 100644 --- a/backend/src/entities/table-settings/personal-table-settings/repository/personal-table-settings.repository.interface.ts +++ b/backend/src/entities/table-settings/personal-table-settings/repository/personal-table-settings.repository.interface.ts @@ -1,9 +1,9 @@ import { PersonalTableSettingsEntity } from '../personal-table-settings.entity.js'; export interface IPersonalTableSettingsRepository { - findUserTableSettings( - userId: string, - connectionId: string, - tableName: string, - ): Promise; + findUserTableSettings( + userId: string, + connectionId: string, + tableName: string, + ): Promise; } diff --git a/backend/src/entities/table-settings/personal-table-settings/use-cases/delete-personal-table-settings.use.case.ts b/backend/src/entities/table-settings/personal-table-settings/use-cases/delete-personal-table-settings.use.case.ts index 0359f812d..64ce1bcfe 100644 --- a/backend/src/entities/table-settings/personal-table-settings/use-cases/delete-personal-table-settings.use.case.ts +++ b/backend/src/entities/table-settings/personal-table-settings/use-cases/delete-personal-table-settings.use.case.ts @@ -1,37 +1,37 @@ import { Inject, Injectable, Scope } from '@nestjs/common'; import AbstractUseCase from '../../../../common/abstract-use.case.js'; +import { IGlobalDatabaseContext } from '../../../../common/application/global-database-context.interface.js'; +import { BaseType } from '../../../../common/data-injection.tokens.js'; import { FindPersonalTableSettingsDs } from '../data-structures/find-personal-table-settings.ds.js'; import { FoundPersonalTableSettingsDto } from '../dto/found-personal-table-settings.dto.js'; -import { IDeletePersonalTableSettings } from './personal-table-settings.use-cases.interface.js'; -import { BaseType } from '../../../../common/data-injection.tokens.js'; -import { IGlobalDatabaseContext } from '../../../../common/application/global-database-context.interface.js'; import { buildFoundTableSettingsDto } from '../utils/build-found-table-settings-dto.js'; +import { IDeletePersonalTableSettings } from './personal-table-settings.use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class DeletePersonalTableSettingsUseCase - extends AbstractUseCase - implements IDeletePersonalTableSettings + extends AbstractUseCase + implements IDeletePersonalTableSettings { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - public async implementation(inputData: FindPersonalTableSettingsDs): Promise { - const { connectionId, userId, tableName } = inputData; + public async implementation(inputData: FindPersonalTableSettingsDs): Promise { + const { connectionId, userId, tableName } = inputData; - const foundPersonalTableSettings = await this._dbContext.personalTableSettingsRepository.findUserTableSettings( - connectionId, - tableName, - userId, - ); + const foundPersonalTableSettings = await this._dbContext.personalTableSettingsRepository.findUserTableSettings( + connectionId, + tableName, + userId, + ); - if (foundPersonalTableSettings) { - await this._dbContext.personalTableSettingsRepository.remove(foundPersonalTableSettings); - } + if (foundPersonalTableSettings) { + await this._dbContext.personalTableSettingsRepository.remove(foundPersonalTableSettings); + } - return buildFoundTableSettingsDto(foundPersonalTableSettings); - } + return buildFoundTableSettingsDto(foundPersonalTableSettings); + } } diff --git a/backend/src/entities/table-settings/personal-table-settings/use-cases/find-personal-table-settings.use.case.ts b/backend/src/entities/table-settings/personal-table-settings/use-cases/find-personal-table-settings.use.case.ts index d789656f8..4ecf29a0a 100644 --- a/backend/src/entities/table-settings/personal-table-settings/use-cases/find-personal-table-settings.use.case.ts +++ b/backend/src/entities/table-settings/personal-table-settings/use-cases/find-personal-table-settings.use.case.ts @@ -10,38 +10,38 @@ import { IFindPersonalTableSettings } from './personal-table-settings.use-cases. @Injectable() export class FindPersonalTableSettingsUseCase - extends AbstractUseCase - implements IFindPersonalTableSettings + extends AbstractUseCase + implements IFindPersonalTableSettings { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - public async implementation(inputData: FindPersonalTableSettingsDs): Promise { - const { connectionId, userId, tableName, masterPassword } = inputData; + public async implementation(inputData: FindPersonalTableSettingsDs): Promise { + const { connectionId, userId, tableName, masterPassword } = inputData; - const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( - connectionId, - masterPassword, - ); + const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( + connectionId, + masterPassword, + ); - if (!foundConnection) { - throw new NotFoundException(Messages.CONNECTION_NOT_FOUND); - } + if (!foundConnection) { + throw new NotFoundException(Messages.CONNECTION_NOT_FOUND); + } - const foundPersonalTableSettings = await this._dbContext.personalTableSettingsRepository.findUserTableSettings( - userId, - connectionId, - tableName, - ); + const foundPersonalTableSettings = await this._dbContext.personalTableSettingsRepository.findUserTableSettings( + userId, + connectionId, + tableName, + ); - if (!foundPersonalTableSettings) { - return {} as FoundPersonalTableSettingsDto; - } + if (!foundPersonalTableSettings) { + return {} as FoundPersonalTableSettingsDto; + } - return buildFoundTableSettingsDto(foundPersonalTableSettings); - } + return buildFoundTableSettingsDto(foundPersonalTableSettings); + } } diff --git a/backend/src/entities/table-settings/personal-table-settings/use-cases/personal-table-settings.use-cases.interface.ts b/backend/src/entities/table-settings/personal-table-settings/use-cases/personal-table-settings.use-cases.interface.ts index fb1e6310a..6455a0fb7 100644 --- a/backend/src/entities/table-settings/personal-table-settings/use-cases/personal-table-settings.use-cases.interface.ts +++ b/backend/src/entities/table-settings/personal-table-settings/use-cases/personal-table-settings.use-cases.interface.ts @@ -4,22 +4,22 @@ import { FindPersonalTableSettingsDs } from '../data-structures/find-personal-ta import { FoundPersonalTableSettingsDto } from '../dto/found-personal-table-settings.dto.js'; export interface IFindPersonalTableSettings { - execute( - inputData: FindPersonalTableSettingsDs, - inTransaction: InTransactionEnum, - ): Promise; + execute( + inputData: FindPersonalTableSettingsDs, + inTransaction: InTransactionEnum, + ): Promise; } export interface ICreateUpdatePersonalTableSettings { - execute( - inputData: CreatePersonalTableSettingsDs, - inTransaction: InTransactionEnum, - ): Promise; + execute( + inputData: CreatePersonalTableSettingsDs, + inTransaction: InTransactionEnum, + ): Promise; } export interface IDeletePersonalTableSettings { - execute( - inputData: FindPersonalTableSettingsDs, - inTransaction: InTransactionEnum, - ): Promise; + execute( + inputData: FindPersonalTableSettingsDs, + inTransaction: InTransactionEnum, + ): Promise; } diff --git a/backend/src/entities/table-settings/personal-table-settings/utils/build-found-table-settings-dto.ts b/backend/src/entities/table-settings/personal-table-settings/utils/build-found-table-settings-dto.ts index f1337b397..730b1e1ec 100644 --- a/backend/src/entities/table-settings/personal-table-settings/utils/build-found-table-settings-dto.ts +++ b/backend/src/entities/table-settings/personal-table-settings/utils/build-found-table-settings-dto.ts @@ -2,16 +2,16 @@ import { FoundPersonalTableSettingsDto } from '../dto/found-personal-table-setti import { PersonalTableSettingsEntity } from '../personal-table-settings.entity.js'; export function buildFoundTableSettingsDto( - personalTableSettings: PersonalTableSettingsEntity, + personalTableSettings: PersonalTableSettingsEntity, ): FoundPersonalTableSettingsDto { - return { - id: personalTableSettings.id, - table_name: personalTableSettings.table_name, - ordering: personalTableSettings.ordering, - ordering_field: personalTableSettings.ordering_field, - list_per_page: personalTableSettings.list_per_page, - list_fields: personalTableSettings.list_fields, - original_names: personalTableSettings.original_names, - columns_view: personalTableSettings.columns_view, - }; + return { + id: personalTableSettings.id, + table_name: personalTableSettings.table_name, + ordering: personalTableSettings.ordering, + ordering_field: personalTableSettings.ordering_field, + list_per_page: personalTableSettings.list_per_page, + list_fields: personalTableSettings.list_fields, + original_names: personalTableSettings.original_names, + columns_view: personalTableSettings.columns_view, + }; } diff --git a/backend/src/entities/table/application/data-structures/add-row-in-table.ds.ts b/backend/src/entities/table/application/data-structures/add-row-in-table.ds.ts index c1a94836f..877254870 100644 --- a/backend/src/entities/table/application/data-structures/add-row-in-table.ds.ts +++ b/backend/src/entities/table/application/data-structures/add-row-in-table.ds.ts @@ -1,7 +1,7 @@ export class AddRowInTableDs { - connectionId: string; - masterPwd: string; - row: Record; - tableName: string; - userId: string; + connectionId: string; + masterPwd: string; + row: Record; + tableName: string; + userId: string; } diff --git a/backend/src/entities/table/application/data-structures/delete-row-from-table.ds.ts b/backend/src/entities/table/application/data-structures/delete-row-from-table.ds.ts index 9c2fec794..367e9c533 100644 --- a/backend/src/entities/table/application/data-structures/delete-row-from-table.ds.ts +++ b/backend/src/entities/table/application/data-structures/delete-row-from-table.ds.ts @@ -1,15 +1,15 @@ export class DeleteRowFromTableDs { - connectionId: string; - masterPwd: string; - primaryKey: Record; - tableName: string; - userId: string; + connectionId: string; + masterPwd: string; + primaryKey: Record; + tableName: string; + userId: string; } export class DeleteRowsFromTableDs { - connectionId: string; - masterPwd: string; - primaryKeys: Array>; - tableName: string; - userId: string; + connectionId: string; + masterPwd: string; + primaryKeys: Array>; + tableName: string; + userId: string; } diff --git a/backend/src/entities/table/application/data-structures/deleted-row-from-table.ds.ts b/backend/src/entities/table/application/data-structures/deleted-row-from-table.ds.ts index 77d2a6875..bcf07d357 100644 --- a/backend/src/entities/table/application/data-structures/deleted-row-from-table.ds.ts +++ b/backend/src/entities/table/application/data-structures/deleted-row-from-table.ds.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; export class DeletedRowFromTableDs { - @ApiProperty() - row: Record; + @ApiProperty() + row: Record; } diff --git a/backend/src/entities/table/application/data-structures/find-tables.ds.ts b/backend/src/entities/table/application/data-structures/find-tables.ds.ts index d8bf9d0d7..a38856542 100644 --- a/backend/src/entities/table/application/data-structures/find-tables.ds.ts +++ b/backend/src/entities/table/application/data-structures/find-tables.ds.ts @@ -1,6 +1,6 @@ export class FindTablesDs { - connectionId: string; - hiddenTablesOption: boolean; - masterPwd: string; - userId: string; + connectionId: string; + hiddenTablesOption: boolean; + masterPwd: string; + userId: string; } diff --git a/backend/src/entities/table/application/data-structures/found-table-rows.ds.ts b/backend/src/entities/table/application/data-structures/found-table-rows.ds.ts index be0745da3..d663ffd2e 100644 --- a/backend/src/entities/table/application/data-structures/found-table-rows.ds.ts +++ b/backend/src/entities/table/application/data-structures/found-table-rows.ds.ts @@ -1,13 +1,13 @@ -import { FilterCriteriaEnum, QueryOrderingEnum } from '../../../../enums/index.js'; -import { FullTableStructureDs } from './found-table-structure.ds.js'; -import { TableWidgetEntity } from '../../../widget/table-widget.entity.js'; +import { ApiProperty } from '@nestjs/swagger'; import { ForeignKeyDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key.ds.js'; import { PrimaryKeyDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/primary-key.ds.js'; import { RowsPaginationDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/rows-pagination.ds.js'; -import { ApiProperty } from '@nestjs/swagger'; +import { FilterCriteriaEnum, QueryOrderingEnum } from '../../../../enums/index.js'; import { TablePermissionDs } from '../../../permission/application/data-structures/create-permissions.ds.js'; import { FoundActionEventDTO } from '../../../table-actions/table-action-rules-module/application/dto/found-action-rules-with-actions-and-events.dto.js'; import { CreatedTableFilterRO } from '../../../table-filters/application/response-objects/created-table-filters.ro.js'; +import { TableWidgetEntity } from '../../../widget/table-widget.entity.js'; +import { FullTableStructureDs } from './found-table-structure.ds.js'; export class TableSettingsInRowsDS { @ApiProperty({ isArray: true }) diff --git a/backend/src/entities/table/application/data-structures/found-table-structure.ds.ts b/backend/src/entities/table/application/data-structures/found-table-structure.ds.ts index 831abbc7d..49ba607a5 100644 --- a/backend/src/entities/table/application/data-structures/found-table-structure.ds.ts +++ b/backend/src/entities/table/application/data-structures/found-table-structure.ds.ts @@ -1,30 +1,30 @@ import { ApiProperty } from '@nestjs/swagger'; export class FullTableStructureDs { - @ApiProperty() - column_name: string; + @ApiProperty() + column_name: string; - @ApiProperty() - column_default: string | number; + @ApiProperty() + column_default: string | number; - @ApiProperty() - data_type: string; + @ApiProperty() + data_type: string; - @ApiProperty() - data_type_params: string; + @ApiProperty() + data_type_params: string; - @ApiProperty() - isExcluded: boolean; + @ApiProperty() + isExcluded: boolean; - @ApiProperty() - isSearched: boolean; + @ApiProperty() + isSearched: boolean; - @ApiProperty() - auto_increment: boolean; + @ApiProperty() + auto_increment: boolean; - @ApiProperty() - allow_null: boolean; + @ApiProperty() + allow_null: boolean; - @ApiProperty() - character_maximum_length: number; + @ApiProperty() + character_maximum_length: number; } diff --git a/backend/src/entities/table/application/data-structures/found-table.ds.ts b/backend/src/entities/table/application/data-structures/found-table.ds.ts index 628025a12..8a3f9ca26 100644 --- a/backend/src/entities/table/application/data-structures/found-table.ds.ts +++ b/backend/src/entities/table/application/data-structures/found-table.ds.ts @@ -3,26 +3,26 @@ import { TableAccessLevelsDs } from '../../../permission/application/data-struct import { FoundTableCategoryRo } from '../../../table-categories/dto/found-table-category.ro.js'; export class FoundTableDs { - @ApiProperty() - display_name?: string; + @ApiProperty() + display_name?: string; - @ApiProperty() - table: string; + @ApiProperty() + table: string; - @ApiProperty() - isView: boolean; + @ApiProperty() + isView: boolean; - @ApiProperty() - icon: string; + @ApiProperty() + icon: string; - @ApiProperty() - permissions: TableAccessLevelsDs; + @ApiProperty() + permissions: TableAccessLevelsDs; } export class FoundTablesWithCategoriesDS { - @ApiProperty({ type: FoundTableDs, isArray: true }) - tables: Array; + @ApiProperty({ type: FoundTableDs, isArray: true }) + tables: Array; - @ApiProperty({ type: FoundTableCategoryRo, isArray: true }) - table_categories: FoundTableCategoryRo[]; + @ApiProperty({ type: FoundTableCategoryRo, isArray: true }) + table_categories: FoundTableCategoryRo[]; } diff --git a/backend/src/entities/table/application/data-structures/get-row-by-primary-key.ds.ts b/backend/src/entities/table/application/data-structures/get-row-by-primary-key.ds.ts index 82ddc1295..9e9064b1a 100644 --- a/backend/src/entities/table/application/data-structures/get-row-by-primary-key.ds.ts +++ b/backend/src/entities/table/application/data-structures/get-row-by-primary-key.ds.ts @@ -1,7 +1,7 @@ export class GetRowByPrimaryKeyDs { - connectionId: string; - masterPwd: string; - primaryKey: Record; - tableName: string; - userId: string; + connectionId: string; + masterPwd: string; + primaryKey: Record; + tableName: string; + userId: string; } diff --git a/backend/src/entities/table/application/data-structures/get-table-rows.ds.ts b/backend/src/entities/table/application/data-structures/get-table-rows.ds.ts index e5fcc285a..938c7e411 100644 --- a/backend/src/entities/table/application/data-structures/get-table-rows.ds.ts +++ b/backend/src/entities/table/application/data-structures/get-table-rows.ds.ts @@ -1,11 +1,11 @@ export class GetTableRowsDs { - connectionId: string; - masterPwd: string; - page: number; - perPage: number; - query: Record; - searchingFieldValue: string; - tableName: string; - userId: string; - filters?: Record; + connectionId: string; + masterPwd: string; + page: number; + perPage: number; + query: Record; + searchingFieldValue: string; + tableName: string; + userId: string; + filters?: Record; } diff --git a/backend/src/entities/table/application/data-structures/get-table-structure-ds.ts b/backend/src/entities/table/application/data-structures/get-table-structure-ds.ts index 7d2570dd3..e7fc227d0 100644 --- a/backend/src/entities/table/application/data-structures/get-table-structure-ds.ts +++ b/backend/src/entities/table/application/data-structures/get-table-structure-ds.ts @@ -1,6 +1,6 @@ export class GetTableStructureDs { - connectionId: string; - masterPwd: string; - tableName: string; - userId: string; + connectionId: string; + masterPwd: string; + tableName: string; + userId: string; } diff --git a/backend/src/entities/table/application/data-structures/import-scv-in-table.ds.ts b/backend/src/entities/table/application/data-structures/import-scv-in-table.ds.ts index 1a41ce6ec..5db90d0b4 100644 --- a/backend/src/entities/table/application/data-structures/import-scv-in-table.ds.ts +++ b/backend/src/entities/table/application/data-structures/import-scv-in-table.ds.ts @@ -1,7 +1,7 @@ export class ImportCSVInTableDs { - file: Express.Multer.File; - tableName: string; - connectionId: string; - materPwd: string; - userId: string; -} \ No newline at end of file + file: Express.Multer.File; + tableName: string; + connectionId: string; + materPwd: string; + userId: string; +} diff --git a/backend/src/entities/table/application/data-structures/pagination.ds.ts b/backend/src/entities/table/application/data-structures/pagination.ds.ts index 590003dea..8a8b9749c 100644 --- a/backend/src/entities/table/application/data-structures/pagination.ds.ts +++ b/backend/src/entities/table/application/data-structures/pagination.ds.ts @@ -1,15 +1,15 @@ import { ApiProperty } from '@nestjs/swagger'; export class PaginationDs { - @ApiProperty() - currentPage: number; + @ApiProperty() + currentPage: number; - @ApiProperty() - lastPage: number; + @ApiProperty() + lastPage: number; - @ApiProperty() - perPage: number; + @ApiProperty() + perPage: number; - @ApiProperty() - total: number; + @ApiProperty() + total: number; } diff --git a/backend/src/entities/table/application/data-structures/update-row-in-table.ds.ts b/backend/src/entities/table/application/data-structures/update-row-in-table.ds.ts index bb34635f1..05538f036 100644 --- a/backend/src/entities/table/application/data-structures/update-row-in-table.ds.ts +++ b/backend/src/entities/table/application/data-structures/update-row-in-table.ds.ts @@ -1,5 +1,5 @@ import { AddRowInTableDs } from './add-row-in-table.ds.js'; export class UpdateRowInTableDs extends AddRowInTableDs { - primaryKey: Record; + primaryKey: Record; } diff --git a/backend/src/entities/table/application/data-structures/update-rows-in-table.ds.ts b/backend/src/entities/table/application/data-structures/update-rows-in-table.ds.ts index fda7f88c9..2973a56a1 100644 --- a/backend/src/entities/table/application/data-structures/update-rows-in-table.ds.ts +++ b/backend/src/entities/table/application/data-structures/update-rows-in-table.ds.ts @@ -1,8 +1,8 @@ export class UpdateRowsInTableDs { - connectionId: string; - masterPwd: string; - tableName: string; - userId: string; - primaryKeys: Array>; - newValues: Record; + connectionId: string; + masterPwd: string; + tableName: string; + userId: string; + primaryKeys: Array>; + newValues: Record; } diff --git a/backend/src/entities/table/dto/find-rows-with-body-filters.dto.ts b/backend/src/entities/table/dto/find-rows-with-body-filters.dto.ts index 169b28c83..564fded5e 100644 --- a/backend/src/entities/table/dto/find-rows-with-body-filters.dto.ts +++ b/backend/src/entities/table/dto/find-rows-with-body-filters.dto.ts @@ -2,43 +2,43 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsObject, IsOptional } from 'class-validator'; export class FindAllRowsWithBodyFiltersDto { - @ApiProperty({ - type: 'object', - properties: { - id: { - type: 'object', - properties: { - eq: { type: 'number' }, - }, - }, - name: { - type: 'object', - properties: { - startswith: { type: 'string' }, - }, - }, - age: { - type: 'object', - properties: { - gt: { type: 'number' }, - lt: { type: 'number' }, - }, - }, - }, - example: { - id: { - eq: 1, - }, - name: { - startswith: 'A', - }, - age: { - gt: 18, - lt: 30, - }, - }, - }) - @IsObject() - @IsOptional() - filters: Record; -} \ No newline at end of file + @ApiProperty({ + type: 'object', + properties: { + id: { + type: 'object', + properties: { + eq: { type: 'number' }, + }, + }, + name: { + type: 'object', + properties: { + startswith: { type: 'string' }, + }, + }, + age: { + type: 'object', + properties: { + gt: { type: 'number' }, + lt: { type: 'number' }, + }, + }, + }, + example: { + id: { + eq: 1, + }, + name: { + startswith: 'A', + }, + age: { + gt: 18, + lt: 30, + }, + }, + }) + @IsObject() + @IsOptional() + filters: Record; +} diff --git a/backend/src/entities/table/dto/update-rows.dto.ts b/backend/src/entities/table/dto/update-rows.dto.ts index 3a8045bfa..2add46652 100644 --- a/backend/src/entities/table/dto/update-rows.dto.ts +++ b/backend/src/entities/table/dto/update-rows.dto.ts @@ -2,14 +2,14 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsArray, IsNotEmpty, IsObject } from 'class-validator'; export class UpdateRowsDto { - @ApiProperty() - @IsNotEmpty() - @IsArray() - @IsObject({ each: true }) - primaryKeys: Array>; + @ApiProperty() + @IsNotEmpty() + @IsArray() + @IsObject({ each: true }) + primaryKeys: Array>; - @ApiProperty() - @IsNotEmpty() - @IsObject() - newValues: Record; + @ApiProperty() + @IsNotEmpty() + @IsObject() + newValues: Record; } diff --git a/backend/src/entities/table/table-datastructures.ts b/backend/src/entities/table/table-datastructures.ts index bec915e66..abfe28dfc 100644 --- a/backend/src/entities/table/table-datastructures.ts +++ b/backend/src/entities/table/table-datastructures.ts @@ -6,172 +6,172 @@ import { TableWidgetRO } from '../widget/table-widget.interface.js'; import { TableSettingsInRowsDS } from './application/data-structures/found-table-rows.ds.js'; export class FilteringFieldsDs { - @ApiProperty() - field: string; + @ApiProperty() + field: string; - @ApiProperty({ enum: FilterCriteriaEnum }) - criteria: FilterCriteriaEnum; + @ApiProperty({ enum: FilterCriteriaEnum }) + criteria: FilterCriteriaEnum; - @ApiProperty() - value: string; + @ApiProperty() + value: string; } export class ForeignKeyDSInfo { - @ApiProperty() - referenced_column_name: string; + @ApiProperty() + referenced_column_name: string; - @ApiProperty() - referenced_table_name: string; + @ApiProperty() + referenced_table_name: string; - @ApiProperty() - constraint_name: string; + @ApiProperty() + constraint_name: string; - @ApiProperty() - column_name: string; + @ApiProperty() + column_name: string; } export class ForeignKeyDSStructure { - @ApiProperty() - referenced_column_name: string; + @ApiProperty() + referenced_column_name: string; - @ApiProperty() - referenced_table_name: string; + @ApiProperty() + referenced_table_name: string; - @ApiProperty() - constraint_name: string; + @ApiProperty() + constraint_name: string; - @ApiProperty() - column_name: string; + @ApiProperty() + column_name: string; - @ApiProperty({ isArray: true }) - autocomplete_columns: Array; + @ApiProperty({ isArray: true }) + autocomplete_columns: Array; } export class PrimaryColumnNameDs { - @ApiProperty() - column_name: string; + @ApiProperty() + column_name: string; } export class StructureRowInfoDs { - @ApiProperty() - column_name: string; + @ApiProperty() + column_name: string; - @ApiProperty() - column_default: any; + @ApiProperty() + column_default: any; - @ApiProperty() - data_type: string; + @ApiProperty() + data_type: string; - @ApiProperty() - isExcluded: boolean; + @ApiProperty() + isExcluded: boolean; - @ApiProperty() - isSearched: boolean; + @ApiProperty() + isSearched: boolean; - @ApiProperty() - auto_increment: boolean; + @ApiProperty() + auto_increment: boolean; - @ApiProperty() - allow_null: boolean; + @ApiProperty() + allow_null: boolean; } export class TableStructureDs { - @ApiProperty({ isArray: true, type: StructureRowInfoDs }) - structure: Array; + @ApiProperty({ isArray: true, type: StructureRowInfoDs }) + structure: Array; - @ApiProperty({ isArray: true, type: PrimaryColumnNameDs }) - primaryColumns: Array; + @ApiProperty({ isArray: true, type: PrimaryColumnNameDs }) + primaryColumns: Array; - @ApiProperty({ isArray: true, type: ForeignKeyDSStructure }) - foreignKeys: Array; + @ApiProperty({ isArray: true, type: ForeignKeyDSStructure }) + foreignKeys: Array; - @ApiProperty({ isArray: true }) - readonly_fields: Array; + @ApiProperty({ isArray: true }) + readonly_fields: Array; - @ApiProperty({ isArray: true, type: TableWidgetRO }) - table_widgets: Array; + @ApiProperty({ isArray: true, type: TableWidgetRO }) + table_widgets: Array; - @ApiProperty({ isArray: true }) - list_fields?: Array; + @ApiProperty({ isArray: true }) + list_fields?: Array; - @ApiProperty() - display_name: string; + @ApiProperty() + display_name: string; - @ApiProperty({ isArray: true }) - excluded_fields: Array; + @ApiProperty({ isArray: true }) + excluded_fields: Array; } export class ReferencedByTableInfoDs { - @ApiProperty() - table_name: string; + @ApiProperty() + table_name: string; - @ApiProperty() - display_name: string; + @ApiProperty() + display_name: string; - @ApiProperty() - column_name: string; + @ApiProperty() + column_name: string; } export class ReferencedTableNamesAndColumnsDs { - @ApiProperty({ isArray: true, type: ReferencedByTableInfoDs }) - referenced_by: Array; + @ApiProperty({ isArray: true, type: ReferencedByTableInfoDs }) + referenced_by: Array; - @ApiProperty() - referenced_on_column_name: string; + @ApiProperty() + referenced_on_column_name: string; } export class TableRowRODs { - @ApiProperty() - row: string | Record; + @ApiProperty() + row: string | Record; - @ApiProperty({ isArray: true, type: StructureRowInfoDs }) - structure: Array; + @ApiProperty({ isArray: true, type: StructureRowInfoDs }) + structure: Array; - @ApiProperty({ isArray: true, type: ForeignKeyDSStructure }) - foreignKeys: Array; + @ApiProperty({ isArray: true, type: ForeignKeyDSStructure }) + foreignKeys: Array; - @ApiProperty({ isArray: true, type: PrimaryColumnNameDs }) - primaryColumns: Array; + @ApiProperty({ isArray: true, type: PrimaryColumnNameDs }) + primaryColumns: Array; - @ApiProperty({ isArray: true }) - readonly_fields: Array; + @ApiProperty({ isArray: true }) + readonly_fields: Array; - @ApiProperty({ isArray: true, type: TableWidgetRO }) - table_widgets: Array; + @ApiProperty({ isArray: true, type: TableWidgetRO }) + table_widgets: Array; - @ApiProperty({ isArray: true }) - list_fields: Array; + @ApiProperty({ isArray: true }) + list_fields: Array; - @ApiProperty({ isArray: true }) - excluded_fields: Array; + @ApiProperty({ isArray: true }) + excluded_fields: Array; - @ApiProperty({ isArray: true, type: FoundActionEventDTO }) - action_events?: Array; + @ApiProperty({ isArray: true, type: FoundActionEventDTO }) + action_events?: Array; - @ApiProperty({ isArray: true, type: FoundActionEventDTO }) - table_actions?: Array; + @ApiProperty({ isArray: true, type: FoundActionEventDTO }) + table_actions?: Array; - @ApiProperty() - identity_column: string; + @ApiProperty() + identity_column: string; - @ApiProperty() - display_name: string; + @ApiProperty() + display_name: string; - @ApiProperty() - table_access_level?: TableAccessLevelsDs; + @ApiProperty() + table_access_level?: TableAccessLevelsDs; - @ApiProperty({ isArray: true, type: ReferencedTableNamesAndColumnsDs }) - referenced_table_names_and_columns: Array; + @ApiProperty({ isArray: true, type: ReferencedTableNamesAndColumnsDs }) + referenced_table_names_and_columns: Array; - @ApiProperty() - can_delete: boolean; + @ApiProperty() + can_delete: boolean; - @ApiProperty() - can_update: boolean; + @ApiProperty() + can_update: boolean; - @ApiProperty() - can_add: boolean; + @ApiProperty() + can_add: boolean; - @ApiProperty({ type: TableSettingsInRowsDS }) - table_settings: TableSettingsInRowsDS; + @ApiProperty({ type: TableSettingsInRowsDS }) + table_settings: TableSettingsInRowsDS; } diff --git a/backend/src/entities/table/table.controller.ts b/backend/src/entities/table/table.controller.ts index 07ce7808b..d29fbd8fa 100644 --- a/backend/src/entities/table/table.controller.ts +++ b/backend/src/entities/table/table.controller.ts @@ -22,6 +22,7 @@ import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-acce import { IGlobalDatabaseContext } from '../../common/application/global-database-context.interface.js'; import { BaseType, UseCaseType } from '../../common/data-injection.tokens.js'; import { MasterPassword, QueryTableName, SlugUuid, UserId } from '../../decorators/index.js'; +import { Timeout, TimeoutDefaults } from '../../decorators/timeout.decorator.js'; import { AmplitudeEventTypeEnum, InTransactionEnum } from '../../enums/index.js'; import { Messages } from '../../exceptions/text/messages.js'; import { TableAddGuard, TableDeleteGuard, TableEditGuard, TableReadGuard } from '../../guards/index.js'; @@ -36,8 +37,8 @@ import { AddRowInTableDs } from './application/data-structures/add-row-in-table. import { DeleteRowFromTableDs, DeleteRowsFromTableDs } from './application/data-structures/delete-row-from-table.ds.js'; import { DeletedRowFromTableDs } from './application/data-structures/deleted-row-from-table.ds.js'; import { FindTablesDs } from './application/data-structures/find-tables.ds.js'; -import { FoundTableRowsDs } from './application/data-structures/found-table-rows.ds.js'; import { FoundTableDs, FoundTablesWithCategoriesDS } from './application/data-structures/found-table.ds.js'; +import { FoundTableRowsDs } from './application/data-structures/found-table-rows.ds.js'; import { GetRowByPrimaryKeyDs } from './application/data-structures/get-row-by-primary-key.ds.js'; import { GetTableRowsDs } from './application/data-structures/get-table-rows.ds.js'; import { GetTableStructureDs } from './application/data-structures/get-table-structure-ds.js'; @@ -61,7 +62,6 @@ import { IImportCSVFinTable, IUpdateRowInTable, } from './use-cases/table-use-cases.interface.js'; -import { Timeout, TimeoutDefaults } from '../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/table/table.module.ts b/backend/src/entities/table/table.module.ts index 719983a8c..0dc1470ab 100644 --- a/backend/src/entities/table/table.module.ts +++ b/backend/src/entities/table/table.module.ts @@ -1,11 +1,12 @@ import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthWithApiMiddleware } from '../../authorization/auth-with-api.middleware.js'; import { GlobalDatabaseContext } from '../../common/application/global-database-context.js'; import { BaseType, UseCaseType } from '../../common/data-injection.tokens.js'; import { AgentModule } from '../agent/agent.module.js'; -import { ConnectionPropertiesEntity } from '../connection-properties/connection-properties.entity.js'; import { ConnectionEntity } from '../connection/connection.entity.js'; import { ConnectionModule } from '../connection/connection.module.js'; +import { ConnectionPropertiesEntity } from '../connection-properties/connection-properties.entity.js'; import { CustomFieldsEntity } from '../custom-field/custom-fields.entity.js'; import { GroupEntity } from '../group/group.entity.js'; import { LogOutEntity } from '../log-out/log-out.entity.js'; @@ -17,114 +18,113 @@ import { UserModule } from '../user/user.module.js'; import { TableWidgetEntity } from '../widget/table-widget.entity.js'; import { TableController } from './table.controller.js'; import { AddRowInTableUseCase } from './use-cases/add-row-in-table.use.case.js'; +import { BulkUpdateRowsInTableUseCase } from './use-cases/bulk-update-rows-in-table.use.case.js'; import { DeleteRowFromTableUseCase } from './use-cases/delete-row-from-table.use.case.js'; import { DeleteRowsFromTableUseCase } from './use-cases/delete-rows-from-table.use.case.js'; +import { ExportCSVFromTableUseCase } from './use-cases/export-csv-from-table.use.case.js'; import { FindTablesInConnectionUseCase } from './use-cases/find-tables-in-connection.use.case.js'; +import { FindTablesInConnectionV2UseCase } from './use-cases/find-tables-in-connection-v2.use.case.js'; import { GetRowByPrimaryKeyUseCase } from './use-cases/get-row-by-primary-key.use.case.js'; import { GetTableRowsUseCase } from './use-cases/get-table-rows.use.case.js'; import { GetTableStructureUseCase } from './use-cases/get-table-structure.use.case.js'; -import { UpdateRowInTableUseCase } from './use-cases/update-row-in-table.use.case.js'; -import { ExportCSVFromTableUseCase } from './use-cases/export-csv-from-table.use.case.js'; -import { BulkUpdateRowsInTableUseCase } from './use-cases/bulk-update-rows-in-table.use.case.js'; import { ImportCSVInTableUseCase } from './use-cases/import-csv-in-table-user.case.js'; -import { AuthWithApiMiddleware } from '../../authorization/auth-with-api.middleware.js'; -import { FindTablesInConnectionV2UseCase } from './use-cases/find-tables-in-connection-v2.use.case.js'; +import { UpdateRowInTableUseCase } from './use-cases/update-row-in-table.use.case.js'; @Module({ - imports: [ - TypeOrmModule.forFeature([ - ConnectionEntity, - CustomFieldsEntity, - GroupEntity, - PermissionEntity, - TableLogsEntity, - TableSettingsEntity, - TableWidgetEntity, - UserEntity, - ConnectionPropertiesEntity, - LogOutEntity, - ]), - AgentModule, - ConnectionModule, - UserModule, - ], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.FIND_TABLES_IN_CONNECTION, - useClass: FindTablesInConnectionUseCase, - }, - { - provide: UseCaseType.FIND_TABLES_IN_CONNECTION_V2, - useClass: FindTablesInConnectionV2UseCase, - }, - { - provide: UseCaseType.GET_ALL_TABLE_ROWS, - useClass: GetTableRowsUseCase, - }, - { - provide: UseCaseType.GET_TABLE_STRUCTURE, - useClass: GetTableStructureUseCase, - }, - { - provide: UseCaseType.ADD_ROW_IN_TABLE, - useClass: AddRowInTableUseCase, - }, - { - provide: UseCaseType.UPDATE_ROW_IN_TABLE, - useClass: UpdateRowInTableUseCase, - }, - { - provide: UseCaseType.DELETE_ROW_FROM_TABLE, - useClass: DeleteRowFromTableUseCase, - }, - { - provide: UseCaseType.DELETE_ROWS_FROM_TABLE, - useClass: DeleteRowsFromTableUseCase, - }, - { - provide: UseCaseType.GET_ROW_BY_PRIMARY_KEY, - useClass: GetRowByPrimaryKeyUseCase, - }, - { - provide: UseCaseType.EXPORT_CSV_FROM_TABLE, - useClass: ExportCSVFromTableUseCase, - }, - { - provide: UseCaseType.BULK_UPDATE_ROWS_IN_TABLE, - useClass: BulkUpdateRowsInTableUseCase, - }, - { - provide: UseCaseType.IMPORT_CSV_TO_TABLE, - useClass: ImportCSVInTableUseCase, - }, - ], - controllers: [TableController], + imports: [ + TypeOrmModule.forFeature([ + ConnectionEntity, + CustomFieldsEntity, + GroupEntity, + PermissionEntity, + TableLogsEntity, + TableSettingsEntity, + TableWidgetEntity, + UserEntity, + ConnectionPropertiesEntity, + LogOutEntity, + ]), + AgentModule, + ConnectionModule, + UserModule, + ], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.FIND_TABLES_IN_CONNECTION, + useClass: FindTablesInConnectionUseCase, + }, + { + provide: UseCaseType.FIND_TABLES_IN_CONNECTION_V2, + useClass: FindTablesInConnectionV2UseCase, + }, + { + provide: UseCaseType.GET_ALL_TABLE_ROWS, + useClass: GetTableRowsUseCase, + }, + { + provide: UseCaseType.GET_TABLE_STRUCTURE, + useClass: GetTableStructureUseCase, + }, + { + provide: UseCaseType.ADD_ROW_IN_TABLE, + useClass: AddRowInTableUseCase, + }, + { + provide: UseCaseType.UPDATE_ROW_IN_TABLE, + useClass: UpdateRowInTableUseCase, + }, + { + provide: UseCaseType.DELETE_ROW_FROM_TABLE, + useClass: DeleteRowFromTableUseCase, + }, + { + provide: UseCaseType.DELETE_ROWS_FROM_TABLE, + useClass: DeleteRowsFromTableUseCase, + }, + { + provide: UseCaseType.GET_ROW_BY_PRIMARY_KEY, + useClass: GetRowByPrimaryKeyUseCase, + }, + { + provide: UseCaseType.EXPORT_CSV_FROM_TABLE, + useClass: ExportCSVFromTableUseCase, + }, + { + provide: UseCaseType.BULK_UPDATE_ROWS_IN_TABLE, + useClass: BulkUpdateRowsInTableUseCase, + }, + { + provide: UseCaseType.IMPORT_CSV_TO_TABLE, + useClass: ImportCSVInTableUseCase, + }, + ], + controllers: [TableController], }) export class TableModule { - public configure(consumer: MiddlewareConsumer): any { - consumer - .apply(AuthWithApiMiddleware) - .forRoutes( - { path: '/table/columns/:connectionId', method: RequestMethod.GET }, - { path: '/table/rows/:connectionId', method: RequestMethod.GET }, - { path: '/table/:connectionId', method: RequestMethod.GET }, - { path: '/connection/tables/:connectionId', method: RequestMethod.GET }, - { path: '/connection/tables/v2/:connectionId', method: RequestMethod.GET }, - { path: '/table/rows/:connectionId', method: RequestMethod.GET }, - { path: '/table/rows/find/:connectionId', method: RequestMethod.POST }, - { path: '/table/structure/:connectionId', method: RequestMethod.GET }, - { path: '/table/row/:connectionId', method: RequestMethod.POST }, - { path: '/table/row/:connectionId', method: RequestMethod.PUT }, - { path: '/table/row/:connectionId', method: RequestMethod.DELETE }, - { path: '/table/rows/delete/:connectionId', method: RequestMethod.PUT }, - { path: '/table/rows/update/:connectionId', method: RequestMethod.PUT }, - { path: '/table/row/:connectionId', method: RequestMethod.GET }, - { path: '/table/csv/export/:connectionId', method: RequestMethod.POST }, - { path: '/table/csv/import/:connectionId', method: RequestMethod.POST }, - ); - } + public configure(consumer: MiddlewareConsumer): any { + consumer + .apply(AuthWithApiMiddleware) + .forRoutes( + { path: '/table/columns/:connectionId', method: RequestMethod.GET }, + { path: '/table/rows/:connectionId', method: RequestMethod.GET }, + { path: '/table/:connectionId', method: RequestMethod.GET }, + { path: '/connection/tables/:connectionId', method: RequestMethod.GET }, + { path: '/connection/tables/v2/:connectionId', method: RequestMethod.GET }, + { path: '/table/rows/:connectionId', method: RequestMethod.GET }, + { path: '/table/rows/find/:connectionId', method: RequestMethod.POST }, + { path: '/table/structure/:connectionId', method: RequestMethod.GET }, + { path: '/table/row/:connectionId', method: RequestMethod.POST }, + { path: '/table/row/:connectionId', method: RequestMethod.PUT }, + { path: '/table/row/:connectionId', method: RequestMethod.DELETE }, + { path: '/table/rows/delete/:connectionId', method: RequestMethod.PUT }, + { path: '/table/rows/update/:connectionId', method: RequestMethod.PUT }, + { path: '/table/row/:connectionId', method: RequestMethod.GET }, + { path: '/table/csv/export/:connectionId', method: RequestMethod.POST }, + { path: '/table/csv/import/:connectionId', method: RequestMethod.POST }, + ); + } } diff --git a/backend/src/entities/table/use-cases/add-row-in-table.use.case.ts b/backend/src/entities/table/use-cases/add-row-in-table.use.case.ts index 2b98b5eaf..c1584a1a2 100644 --- a/backend/src/entities/table/use-cases/add-row-in-table.use.case.ts +++ b/backend/src/entities/table/use-cases/add-row-in-table.use.case.ts @@ -1,10 +1,10 @@ import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; -import { ForeignKeyWithAutocompleteColumnsDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key-with-autocomplete-columns.ds.js'; import { ForeignKeyDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key.ds.js'; -import { IDataAccessObjectAgent } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object-agent.interface.js'; -import { IDataAccessObject } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object.interface.js'; +import { ForeignKeyWithAutocompleteColumnsDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key-with-autocomplete-columns.ds.js'; import { buildDAOsTableSettingsDs } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/table-settings.ds.builder.js'; +import { IDataAccessObject } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object.interface.js'; +import { IDataAccessObjectAgent } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object-agent.interface.js'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; diff --git a/backend/src/entities/table/use-cases/bulk-update-rows-in-table.use.case.ts b/backend/src/entities/table/use-cases/bulk-update-rows-in-table.use.case.ts index ea5c3a3d0..7a918d39c 100644 --- a/backend/src/entities/table/use-cases/bulk-update-rows-in-table.use.case.ts +++ b/backend/src/entities/table/use-cases/bulk-update-rows-in-table.use.case.ts @@ -1,138 +1,138 @@ import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; +import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; +import { buildDAOsTableSettingsDs } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/table-settings.ds.builder.js'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; -import { UpdateRowsInTableDs } from '../application/data-structures/update-rows-in-table.ds.js'; -import { IBulkUpdateRowsInTable } from './table-use-cases.interface.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import { TableLogsService } from '../../table-logs/table-logs.service.js'; +import { LogOperationTypeEnum } from '../../../enums/log-operation-type.enum.js'; +import { OperationResultStatusEnum } from '../../../enums/operation-result-status.enum.js'; +import { ExceptionOperations } from '../../../exceptions/custom-exceptions/exception-operation.js'; +import { NonAvailableInFreePlanException } from '../../../exceptions/custom-exceptions/non-available-in-free-plan-exception.js'; +import { UnknownSQLException } from '../../../exceptions/custom-exceptions/unknown-sql-exception.js'; import { Messages } from '../../../exceptions/text/messages.js'; -import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import { isConnectionTypeAgent } from '../../../helpers/is-connection-entity-agent.js'; +import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; +import { TableLogsService } from '../../table-logs/table-logs.service.js'; +import { UpdateRowsInTableDs } from '../application/data-structures/update-rows-in-table.ds.js'; import { convertHexDataInPrimaryKeyUtil } from '../utils/convert-hex-data-in-primary-key.util.js'; -import { UnknownSQLException } from '../../../exceptions/custom-exceptions/unknown-sql-exception.js'; -import { ExceptionOperations } from '../../../exceptions/custom-exceptions/exception-operation.js'; import { hashPasswordsInRowUtil } from '../utils/hash-passwords-in-row.util.js'; import { processUuidsInRowUtil } from '../utils/process-uuids-in-row-util.js'; -import { OperationResultStatusEnum } from '../../../enums/operation-result-status.enum.js'; -import { LogOperationTypeEnum } from '../../../enums/log-operation-type.enum.js'; -import { NonAvailableInFreePlanException } from '../../../exceptions/custom-exceptions/non-available-in-free-plan-exception.js'; -import { buildDAOsTableSettingsDs } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/table-settings.ds.builder.js'; +import { IBulkUpdateRowsInTable } from './table-use-cases.interface.js'; @Injectable() export class BulkUpdateRowsInTableUseCase - extends AbstractUseCase - implements IBulkUpdateRowsInTable + extends AbstractUseCase + implements IBulkUpdateRowsInTable { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private tableLogsService: TableLogsService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private tableLogsService: TableLogsService, + ) { + super(); + } - protected async implementation(inputData: UpdateRowsInTableDs): Promise { - const { connectionId, masterPwd, newValues, primaryKeys, tableName, userId } = inputData; - let operationResult = OperationResultStatusEnum.unknown; + protected async implementation(inputData: UpdateRowsInTableDs): Promise { + const { connectionId, masterPwd, newValues, primaryKeys, tableName, userId } = inputData; + let operationResult = OperationResultStatusEnum.unknown; - if (!primaryKeys?.length) { - throw new HttpException( - { - message: Messages.PRIMARY_KEY_MISSING, - }, - HttpStatus.BAD_REQUEST, - ); - } + if (!primaryKeys?.length) { + throw new HttpException( + { + message: Messages.PRIMARY_KEY_MISSING, + }, + HttpStatus.BAD_REQUEST, + ); + } - const connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, masterPwd); - if (!connection) { - throw new HttpException( - { - message: Messages.CONNECTION_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } + const connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, masterPwd); + if (!connection) { + throw new HttpException( + { + message: Messages.CONNECTION_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } - if (connection.is_frozen) { - throw new NonAvailableInFreePlanException(Messages.CONNECTION_IS_FROZEN); - } + if (connection.is_frozen) { + throw new NonAvailableInFreePlanException(Messages.CONNECTION_IS_FROZEN); + } - const dao = getDataAccessObject(connection); - let userEmail: string; - if (isConnectionTypeAgent(connection.type)) { - userEmail = await this._dbContext.userRepository.getUserEmailOrReturnNull(userId); - } + const dao = getDataAccessObject(connection); + let userEmail: string; + if (isConnectionTypeAgent(connection.type)) { + userEmail = await this._dbContext.userRepository.getUserEmailOrReturnNull(userId); + } - const isView = await dao.isView(tableName, userEmail); - if (isView) { - throw new HttpException( - { - message: Messages.CANT_UPDATE_TABLE_VIEW, - }, - HttpStatus.BAD_REQUEST, - ); - } + const isView = await dao.isView(tableName, userEmail); + if (isView) { + throw new HttpException( + { + message: Messages.CANT_UPDATE_TABLE_VIEW, + }, + HttpStatus.BAD_REQUEST, + ); + } - const [tableStructure, primaryColumns, tableSettings, personalTableSettings, tableWidgets] = await Promise.all([ - dao.getTableStructure(tableName, userEmail), - dao.getTablePrimaryColumns(tableName, userEmail), - this._dbContext.tableSettingsRepository.findTableSettings(connectionId, tableName), - this._dbContext.personalTableSettingsRepository.findUserTableSettings(userId, connectionId, tableName), - this._dbContext.tableWidgetsRepository.findTableWidgets(connectionId, tableName), - ]); + const [tableStructure, primaryColumns, tableSettings, personalTableSettings, tableWidgets] = await Promise.all([ + dao.getTableStructure(tableName, userEmail), + dao.getTablePrimaryColumns(tableName, userEmail), + this._dbContext.tableSettingsRepository.findTableSettings(connectionId, tableName), + this._dbContext.personalTableSettingsRepository.findUserTableSettings(userId, connectionId, tableName), + this._dbContext.tableWidgetsRepository.findTableWidgets(connectionId, tableName), + ]); - primaryKeys.forEach((primaryKey) => { - convertHexDataInPrimaryKeyUtil(primaryKey, tableStructure); - }); + primaryKeys.forEach((primaryKey) => { + convertHexDataInPrimaryKeyUtil(primaryKey, tableStructure); + }); - const availablePrimaryColumns: Array = primaryColumns.map((column) => column.column_name); + const availablePrimaryColumns: Array = primaryColumns.map((column) => column.column_name); - for (const key of primaryKeys) { - const receivedPrimaryColumns = Object.keys(key); - if (!availablePrimaryColumns.every((column) => receivedPrimaryColumns.includes(column))) { - throw new HttpException( - { - message: Messages.PRIMARY_KEY_MISSING_PARAMETER_OR_INCORRECT, - }, - HttpStatus.BAD_REQUEST, - ); - } - } + for (const key of primaryKeys) { + const receivedPrimaryColumns = Object.keys(key); + if (!availablePrimaryColumns.every((column) => receivedPrimaryColumns.includes(column))) { + throw new HttpException( + { + message: Messages.PRIMARY_KEY_MISSING_PARAMETER_OR_INCORRECT, + }, + HttpStatus.BAD_REQUEST, + ); + } + } - const builtDAOsTableSettings = buildDAOsTableSettingsDs(tableSettings, personalTableSettings); - const oldRowsData: Array> = await Promise.all( - primaryKeys.map((primaryKey) => dao.getRowByPrimaryKey(tableName, primaryKey, builtDAOsTableSettings, userEmail)), - ); + const builtDAOsTableSettings = buildDAOsTableSettingsDs(tableSettings, personalTableSettings); + const oldRowsData: Array> = await Promise.all( + primaryKeys.map((primaryKey) => dao.getRowByPrimaryKey(tableName, primaryKey, builtDAOsTableSettings, userEmail)), + ); - try { - let processedNewValues = await hashPasswordsInRowUtil(newValues, tableWidgets); - processedNewValues = processUuidsInRowUtil(processedNewValues, tableWidgets); - await dao.bulkUpdateRowsInTable(tableName, processedNewValues, primaryKeys, userEmail); - operationResult = OperationResultStatusEnum.successfully; - return { - success: true, - }; - } catch (e) { - operationResult = OperationResultStatusEnum.unsuccessfully; - throw new UnknownSQLException(e.message, ExceptionOperations.FAILED_TO_UPDATE_ROWS_IN_TABLE); - } finally { - const logsData = oldRowsData.map((oldRowData) => { - return { - operationStatusResult: operationResult, - row: newValues, - old_data: oldRowData, - affected_primary_key: primaryKeys as unknown as string, - }; - }); - await this.tableLogsService.createAndSaveNewLogsUtil( - logsData, - userId, - connection, - tableName, - LogOperationTypeEnum.updateRow, - ); - } - } + try { + let processedNewValues = await hashPasswordsInRowUtil(newValues, tableWidgets); + processedNewValues = processUuidsInRowUtil(processedNewValues, tableWidgets); + await dao.bulkUpdateRowsInTable(tableName, processedNewValues, primaryKeys, userEmail); + operationResult = OperationResultStatusEnum.successfully; + return { + success: true, + }; + } catch (e) { + operationResult = OperationResultStatusEnum.unsuccessfully; + throw new UnknownSQLException(e.message, ExceptionOperations.FAILED_TO_UPDATE_ROWS_IN_TABLE); + } finally { + const logsData = oldRowsData.map((oldRowData) => { + return { + operationStatusResult: operationResult, + row: newValues, + old_data: oldRowData, + affected_primary_key: primaryKeys as unknown as string, + }; + }); + await this.tableLogsService.createAndSaveNewLogsUtil( + logsData, + userId, + connection, + tableName, + LogOperationTypeEnum.updateRow, + ); + } + } } diff --git a/backend/src/entities/table/use-cases/delete-row-from-table.use.case.ts b/backend/src/entities/table/use-cases/delete-row-from-table.use.case.ts index a56a5b8f0..2e48d94ca 100644 --- a/backend/src/entities/table/use-cases/delete-row-from-table.use.case.ts +++ b/backend/src/entities/table/use-cases/delete-row-from-table.use.case.ts @@ -23,163 +23,163 @@ import { IDeleteRowFromTable } from './table-use-cases.interface.js'; @Injectable() export class DeleteRowFromTableUseCase - extends AbstractUseCase - implements IDeleteRowFromTable + extends AbstractUseCase + implements IDeleteRowFromTable { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private amplitudeService: AmplitudeService, - private tableLogsService: TableLogsService, - private tableActionActivationService: TableActionActivationService, - ) { - super(); - } - - protected async implementation(inputData: DeleteRowFromTableDs): Promise { - // eslint-disable-next-line prefer-const - let { connectionId, masterPwd, primaryKey, tableName, userId } = inputData; - - let operationResult = OperationResultStatusEnum.unknown; - if (!primaryKey) { - throw new HttpException( - { - message: Messages.PRIMARY_KEY_MISSING, - }, - HttpStatus.BAD_REQUEST, - ); - } - - const connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, masterPwd); - if (!connection) { - throw new HttpException( - { - message: Messages.CONNECTION_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - - if (connection.is_frozen) { - throw new NonAvailableInFreePlanException(Messages.CONNECTION_IS_FROZEN); - } - - const dao = getDataAccessObject(connection); - let userEmail: string; - - if (isConnectionTypeAgent(connection.type)) { - userEmail = await this._dbContext.userRepository.getUserEmailOrReturnNull(userId); - } - - const isView = await dao.isView(tableName, userEmail); - if (isView) { - throw new HttpException( - { - message: Messages.CANT_UPDATE_TABLE_VIEW, - }, - HttpStatus.BAD_REQUEST, - ); - } - - const [tableStructure, primaryColumns] = await Promise.all([ - dao.getTableStructure(tableName, userEmail), - dao.getTablePrimaryColumns(tableName, userEmail), - ]); - - primaryKey = convertHexDataInPrimaryKeyUtil(primaryKey, tableStructure); - const availablePrimaryColumns: Array = primaryColumns.map((column) => column.column_name); - - Object.keys(primaryKey).forEach((key) => { - // eslint-disable-next-line security/detect-object-injection - if (!primaryKey[key] && primaryKey[key] !== '') { - // eslint-disable-next-line security/detect-object-injection - delete primaryKey[key]; - } - }); - - const receivedPrimaryColumns = Object.keys(primaryKey); - if (!compareArrayElements(availablePrimaryColumns, receivedPrimaryColumns)) { - throw new HttpException( - { - message: Messages.PRIMARY_KEY_INVALID, - }, - HttpStatus.BAD_REQUEST, - ); - } - - const tableSettings = await this._dbContext.tableSettingsRepository.findTableSettings(connectionId, tableName); - if (tableSettings && !tableSettings?.can_delete) { - throw new HttpException( - { - message: Messages.CANT_DO_TABLE_OPERATION, - }, - HttpStatus.FORBIDDEN, - ); - } - const personalTableSettings = await this._dbContext.personalTableSettingsRepository.findUserTableSettings( - userId, - connectionId, - tableName, - ); - - const builtTableSettings = buildDAOsTableSettingsDs(tableSettings, personalTableSettings); - - let oldRowData: Record; - try { - oldRowData = await dao.getRowByPrimaryKey(tableName, primaryKey, builtTableSettings, userEmail); - } catch (e) { - throw new UnknownSQLException(e.message, ExceptionOperations.FAILED_TO_DELETE_ROW_FROM_TABLE); - } - - if (!oldRowData) { - throw new HttpException( - { - message: Messages.ROW_PRIMARY_KEY_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - - try { - await dao.deleteRowInTable(tableName, primaryKey, userEmail); - operationResult = OperationResultStatusEnum.successfully; - return { - row: oldRowData, - }; - } catch (e) { - operationResult = OperationResultStatusEnum.unsuccessfully; - throw new DeleteRowException(e.message); - } finally { - const logRecord = { - table_name: tableName, - userId: userId, - connection: connection, - operationType: LogOperationTypeEnum.deleteRow, - operationStatusResult: operationResult, - row: primaryKey, - old_data: oldRowData, - table_primary_key: primaryKey, - }; - await this.tableLogsService.crateAndSaveNewLogUtil(logRecord); - const isTest = isTestConnectionUtil(connection); - await this.amplitudeService.formAndSendLogRecord( - isTest ? AmplitudeEventTypeEnum.tableRowDeletedTest : AmplitudeEventTypeEnum.tableRowDeleted, - userId, - ); - - const foundAddTableActions = await this._dbContext.tableActionRepository.findTableActionsWithDeleteRowEvents( - connectionId, - tableName, - ); - - await this.tableActionActivationService.activateTableActions( - foundAddTableActions, - connection, - primaryKey, - userId, - tableName, - TableActionEventEnum.DELETE_ROW, - ); - } - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private amplitudeService: AmplitudeService, + private tableLogsService: TableLogsService, + private tableActionActivationService: TableActionActivationService, + ) { + super(); + } + + protected async implementation(inputData: DeleteRowFromTableDs): Promise { + // eslint-disable-next-line prefer-const + let { connectionId, masterPwd, primaryKey, tableName, userId } = inputData; + + let operationResult = OperationResultStatusEnum.unknown; + if (!primaryKey) { + throw new HttpException( + { + message: Messages.PRIMARY_KEY_MISSING, + }, + HttpStatus.BAD_REQUEST, + ); + } + + const connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, masterPwd); + if (!connection) { + throw new HttpException( + { + message: Messages.CONNECTION_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + + if (connection.is_frozen) { + throw new NonAvailableInFreePlanException(Messages.CONNECTION_IS_FROZEN); + } + + const dao = getDataAccessObject(connection); + let userEmail: string; + + if (isConnectionTypeAgent(connection.type)) { + userEmail = await this._dbContext.userRepository.getUserEmailOrReturnNull(userId); + } + + const isView = await dao.isView(tableName, userEmail); + if (isView) { + throw new HttpException( + { + message: Messages.CANT_UPDATE_TABLE_VIEW, + }, + HttpStatus.BAD_REQUEST, + ); + } + + const [tableStructure, primaryColumns] = await Promise.all([ + dao.getTableStructure(tableName, userEmail), + dao.getTablePrimaryColumns(tableName, userEmail), + ]); + + primaryKey = convertHexDataInPrimaryKeyUtil(primaryKey, tableStructure); + const availablePrimaryColumns: Array = primaryColumns.map((column) => column.column_name); + + Object.keys(primaryKey).forEach((key) => { + // eslint-disable-next-line security/detect-object-injection + if (!primaryKey[key] && primaryKey[key] !== '') { + // eslint-disable-next-line security/detect-object-injection + delete primaryKey[key]; + } + }); + + const receivedPrimaryColumns = Object.keys(primaryKey); + if (!compareArrayElements(availablePrimaryColumns, receivedPrimaryColumns)) { + throw new HttpException( + { + message: Messages.PRIMARY_KEY_INVALID, + }, + HttpStatus.BAD_REQUEST, + ); + } + + const tableSettings = await this._dbContext.tableSettingsRepository.findTableSettings(connectionId, tableName); + if (tableSettings && !tableSettings?.can_delete) { + throw new HttpException( + { + message: Messages.CANT_DO_TABLE_OPERATION, + }, + HttpStatus.FORBIDDEN, + ); + } + const personalTableSettings = await this._dbContext.personalTableSettingsRepository.findUserTableSettings( + userId, + connectionId, + tableName, + ); + + const builtTableSettings = buildDAOsTableSettingsDs(tableSettings, personalTableSettings); + + let oldRowData: Record; + try { + oldRowData = await dao.getRowByPrimaryKey(tableName, primaryKey, builtTableSettings, userEmail); + } catch (e) { + throw new UnknownSQLException(e.message, ExceptionOperations.FAILED_TO_DELETE_ROW_FROM_TABLE); + } + + if (!oldRowData) { + throw new HttpException( + { + message: Messages.ROW_PRIMARY_KEY_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + + try { + await dao.deleteRowInTable(tableName, primaryKey, userEmail); + operationResult = OperationResultStatusEnum.successfully; + return { + row: oldRowData, + }; + } catch (e) { + operationResult = OperationResultStatusEnum.unsuccessfully; + throw new DeleteRowException(e.message); + } finally { + const logRecord = { + table_name: tableName, + userId: userId, + connection: connection, + operationType: LogOperationTypeEnum.deleteRow, + operationStatusResult: operationResult, + row: primaryKey, + old_data: oldRowData, + table_primary_key: primaryKey, + }; + await this.tableLogsService.crateAndSaveNewLogUtil(logRecord); + const isTest = isTestConnectionUtil(connection); + await this.amplitudeService.formAndSendLogRecord( + isTest ? AmplitudeEventTypeEnum.tableRowDeletedTest : AmplitudeEventTypeEnum.tableRowDeleted, + userId, + ); + + const foundAddTableActions = await this._dbContext.tableActionRepository.findTableActionsWithDeleteRowEvents( + connectionId, + tableName, + ); + + await this.tableActionActivationService.activateTableActions( + foundAddTableActions, + connection, + primaryKey, + userId, + tableName, + TableActionEventEnum.DELETE_ROW, + ); + } + } } diff --git a/backend/src/entities/table/use-cases/delete-rows-from-table.use.case.ts b/backend/src/entities/table/use-cases/delete-rows-from-table.use.case.ts index 398f37a60..2afaee3a0 100644 --- a/backend/src/entities/table/use-cases/delete-rows-from-table.use.case.ts +++ b/backend/src/entities/table/use-cases/delete-rows-from-table.use.case.ts @@ -1,9 +1,11 @@ import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; +import { buildDAOsTableSettingsDs } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/table-settings.ds.builder.js'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { AmplitudeEventTypeEnum, LogOperationTypeEnum, OperationResultStatusEnum } from '../../../enums/index.js'; +import { NonAvailableInFreePlanException } from '../../../exceptions/custom-exceptions/non-available-in-free-plan-exception.js'; import { Messages } from '../../../exceptions/text/messages.js'; import { compareArrayElements, isConnectionTypeAgent } from '../../../helpers/index.js'; import { AmplitudeService } from '../../amplitude/amplitude.service.js'; @@ -13,167 +15,165 @@ import { DeleteRowsFromTableDs } from '../application/data-structures/delete-row import { convertHexDataInPrimaryKeyUtil } from '../utils/convert-hex-data-in-primary-key.util.js'; import { findObjectsWithProperties } from '../utils/find-objects-with-properties.js'; import { IDeleteRowsFromTable } from './table-use-cases.interface.js'; -import { NonAvailableInFreePlanException } from '../../../exceptions/custom-exceptions/non-available-in-free-plan-exception.js'; -import { buildDAOsTableSettingsDs } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/table-settings.ds.builder.js'; type DeleteRowsFromTableResult = { - operationStatusResult: OperationResultStatusEnum; - row: Record; - old_data: Record; - error: string; - affected_primary_key: string; + operationStatusResult: OperationResultStatusEnum; + row: Record; + old_data: Record; + error: string; + affected_primary_key: string; }; @Injectable() export class DeleteRowsFromTableUseCase - extends AbstractUseCase - implements IDeleteRowsFromTable + extends AbstractUseCase + implements IDeleteRowsFromTable { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private amplitudeService: AmplitudeService, - private tableLogsService: TableLogsService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private amplitudeService: AmplitudeService, + private tableLogsService: TableLogsService, + ) { + super(); + } - protected async implementation(inputData: DeleteRowsFromTableDs): Promise { - // eslint-disable-next-line prefer-const - let { connectionId, masterPwd, primaryKeys, tableName, userId } = inputData; - if (!primaryKeys) { - throw new HttpException( - { - message: Messages.PRIMARY_KEY_MISSING, - }, - HttpStatus.BAD_REQUEST, - ); - } - const connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, masterPwd); - if (!connection) { - throw new HttpException( - { - message: Messages.CONNECTION_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } + protected async implementation(inputData: DeleteRowsFromTableDs): Promise { + // eslint-disable-next-line prefer-const + let { connectionId, masterPwd, primaryKeys, tableName, userId } = inputData; + if (!primaryKeys) { + throw new HttpException( + { + message: Messages.PRIMARY_KEY_MISSING, + }, + HttpStatus.BAD_REQUEST, + ); + } + const connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, masterPwd); + if (!connection) { + throw new HttpException( + { + message: Messages.CONNECTION_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } - if (connection.is_frozen) { - throw new NonAvailableInFreePlanException(Messages.CONNECTION_IS_FROZEN); - } + if (connection.is_frozen) { + throw new NonAvailableInFreePlanException(Messages.CONNECTION_IS_FROZEN); + } - const dao = getDataAccessObject(connection); - let userEmail: string; - if (isConnectionTypeAgent(connection.type)) { - userEmail = await this._dbContext.userRepository.getUserEmailOrReturnNull(userId); - } - const isView = await dao.isView(tableName, userEmail); - if (isView) { - throw new HttpException( - { - message: Messages.CANT_UPDATE_TABLE_VIEW, - }, - HttpStatus.BAD_REQUEST, - ); - } + const dao = getDataAccessObject(connection); + let userEmail: string; + if (isConnectionTypeAgent(connection.type)) { + userEmail = await this._dbContext.userRepository.getUserEmailOrReturnNull(userId); + } + const isView = await dao.isView(tableName, userEmail); + if (isView) { + throw new HttpException( + { + message: Messages.CANT_UPDATE_TABLE_VIEW, + }, + HttpStatus.BAD_REQUEST, + ); + } - const [tableStructure, primaryColumns, tableSettings, personalTableSettings] = await Promise.all([ - dao.getTableStructure(tableName, userEmail), - dao.getTablePrimaryColumns(tableName, userEmail), - this._dbContext.tableSettingsRepository.findTableSettings(connectionId, tableName), - this._dbContext.personalTableSettingsRepository.findUserTableSettings(userId, connectionId, tableName), - ]); + const [tableStructure, primaryColumns, tableSettings, personalTableSettings] = await Promise.all([ + dao.getTableStructure(tableName, userEmail), + dao.getTablePrimaryColumns(tableName, userEmail), + this._dbContext.tableSettingsRepository.findTableSettings(connectionId, tableName), + this._dbContext.personalTableSettingsRepository.findUserTableSettings(userId, connectionId, tableName), + ]); - if (tableSettings && !tableSettings?.can_delete) { - throw new HttpException( - { - message: Messages.CANT_DO_TABLE_OPERATION, - }, - HttpStatus.FORBIDDEN, - ); - } + if (tableSettings && !tableSettings?.can_delete) { + throw new HttpException( + { + message: Messages.CANT_DO_TABLE_OPERATION, + }, + HttpStatus.FORBIDDEN, + ); + } - primaryKeys = primaryKeys.map((primaryKey) => convertHexDataInPrimaryKeyUtil(primaryKey, tableStructure)); + primaryKeys = primaryKeys.map((primaryKey) => convertHexDataInPrimaryKeyUtil(primaryKey, tableStructure)); - const availablePrimaryColumns: Array = primaryColumns.map((column) => column.column_name); + const availablePrimaryColumns: Array = primaryColumns.map((column) => column.column_name); - primaryKeys.forEach((primaryKey) => { - Object.keys(primaryKey).forEach((key) => { - // eslint-disable-next-line security/detect-object-injection - if (!primaryKey[key] && primaryKey[key] !== '') { - // eslint-disable-next-line security/detect-object-injection - delete primaryKey[key]; - } - }); + primaryKeys.forEach((primaryKey) => { + Object.keys(primaryKey).forEach((key) => { + // eslint-disable-next-line security/detect-object-injection + if (!primaryKey[key] && primaryKey[key] !== '') { + // eslint-disable-next-line security/detect-object-injection + delete primaryKey[key]; + } + }); - const receivedPrimaryColumns = Object.keys(primaryKey); - if (!compareArrayElements(availablePrimaryColumns, receivedPrimaryColumns)) { - throw new HttpException( - { - message: Messages.PRIMARY_KEY_INVALID, - }, - HttpStatus.BAD_REQUEST, - ); - } - }); - let oldRowsData: Array>; - const builtDAOsTableSettings = buildDAOsTableSettingsDs(tableSettings, personalTableSettings); - try { - oldRowsData = await dao.bulkGetRowsFromTableByPrimaryKeys( - tableName, - primaryKeys, - builtDAOsTableSettings, - userEmail, - ); - } catch (error) { - throw new HttpException( - { - message: Messages.BULK_DELETE_FAILED_GET_ROWS([error.message]), - }, - HttpStatus.INTERNAL_SERVER_ERROR, - ); - } + const receivedPrimaryColumns = Object.keys(primaryKey); + if (!compareArrayElements(availablePrimaryColumns, receivedPrimaryColumns)) { + throw new HttpException( + { + message: Messages.PRIMARY_KEY_INVALID, + }, + HttpStatus.BAD_REQUEST, + ); + } + }); + let oldRowsData: Array>; + const builtDAOsTableSettings = buildDAOsTableSettingsDs(tableSettings, personalTableSettings); + try { + oldRowsData = await dao.bulkGetRowsFromTableByPrimaryKeys( + tableName, + primaryKeys, + builtDAOsTableSettings, + userEmail, + ); + } catch (error) { + throw new HttpException( + { + message: Messages.BULK_DELETE_FAILED_GET_ROWS([error.message]), + }, + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } - const deleteOperationsResults: Array = []; + const deleteOperationsResults: Array = []; - try { - await dao.bulkDeleteRowsInTable(tableName, primaryKeys, userEmail); - primaryKeys.forEach((primaryKey) => { - deleteOperationsResults.push({ - operationStatusResult: OperationResultStatusEnum.successfully, - row: primaryKey, - old_data: findObjectsWithProperties(oldRowsData, primaryKey).at(0), - error: null, - affected_primary_key: primaryKey as unknown as string, - }); - }); - return true; - } catch (error) { - primaryKeys.forEach((primaryKey) => { - deleteOperationsResults.push({ - operationStatusResult: OperationResultStatusEnum.unsuccessfully, - row: primaryKey, - old_data: findObjectsWithProperties(oldRowsData, primaryKey).at(0), - error: error.message, - affected_primary_key: primaryKey as unknown as string, - }); - }); - throw error; - } finally { - const createdLogs = await this.tableLogsService.createAndSaveNewLogsUtil( - deleteOperationsResults, - userId, - connection, - tableName, - LogOperationTypeEnum.deleteRow, - ); - const isTest = isTestConnectionUtil(connection); - await this.amplitudeService.formAndSendLogRecord( - isTest ? AmplitudeEventTypeEnum.tableRowDeletedTest : AmplitudeEventTypeEnum.tableRowDeleted, - userId, - { operationCount: createdLogs.length }, - ); - } - } + try { + await dao.bulkDeleteRowsInTable(tableName, primaryKeys, userEmail); + primaryKeys.forEach((primaryKey) => { + deleteOperationsResults.push({ + operationStatusResult: OperationResultStatusEnum.successfully, + row: primaryKey, + old_data: findObjectsWithProperties(oldRowsData, primaryKey).at(0), + error: null, + affected_primary_key: primaryKey as unknown as string, + }); + }); + return true; + } catch (error) { + primaryKeys.forEach((primaryKey) => { + deleteOperationsResults.push({ + operationStatusResult: OperationResultStatusEnum.unsuccessfully, + row: primaryKey, + old_data: findObjectsWithProperties(oldRowsData, primaryKey).at(0), + error: error.message, + affected_primary_key: primaryKey as unknown as string, + }); + }); + throw error; + } finally { + const createdLogs = await this.tableLogsService.createAndSaveNewLogsUtil( + deleteOperationsResults, + userId, + connection, + tableName, + LogOperationTypeEnum.deleteRow, + ); + const isTest = isTestConnectionUtil(connection); + await this.amplitudeService.formAndSendLogRecord( + isTest ? AmplitudeEventTypeEnum.tableRowDeletedTest : AmplitudeEventTypeEnum.tableRowDeleted, + userId, + { operationCount: createdLogs.length }, + ); + } + } } diff --git a/backend/src/entities/table/use-cases/export-csv-from-table.use.case.ts b/backend/src/entities/table/use-cases/export-csv-from-table.use.case.ts index 74a4d97c6..969a0d4f3 100644 --- a/backend/src/entities/table/use-cases/export-csv-from-table.use.case.ts +++ b/backend/src/entities/table/use-cases/export-csv-from-table.use.case.ts @@ -1,158 +1,158 @@ import { HttpException, HttpStatus, Inject, Injectable, StreamableFile } from '@nestjs/common'; +import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; +import { buildDAOsTableSettingsDs } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/table-settings.ds.builder.js'; +import * as csv from 'csv'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import { GetTableRowsDs } from '../application/data-structures/get-table-rows.ds.js'; -import { IExportCSVFromTable } from './table-use-cases.interface.js'; -import { Messages } from '../../../exceptions/text/messages.js'; import { LogOperationTypeEnum, OperationResultStatusEnum } from '../../../enums/index.js'; +import { NonAvailableInFreePlanException } from '../../../exceptions/custom-exceptions/non-available-in-free-plan-exception.js'; +import { Messages } from '../../../exceptions/text/messages.js'; +import { hexToBinary, isBinary } from '../../../helpers/binary-to-hex.js'; +import { slackPostMessage } from '../../../helpers/index.js'; +import { isConnectionTypeAgent } from '../../../helpers/is-connection-entity-agent.js'; +import { isObjectEmpty } from '../../../helpers/is-object-empty.js'; import { TableLogsService } from '../../table-logs/table-logs.service.js'; +import { GetTableRowsDs } from '../application/data-structures/get-table-rows.ds.js'; +import { FilteringFieldsDs } from '../table-datastructures.js'; import { findFilteringFieldsUtil, parseFilteringFieldsFromBodyData } from '../utils/find-filtering-fields.util.js'; import { findOrderingFieldUtil } from '../utils/find-ordering-field.util.js'; -import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; -import { isConnectionTypeAgent } from '../../../helpers/is-connection-entity-agent.js'; -import { hexToBinary, isBinary } from '../../../helpers/binary-to-hex.js'; import { isHexString } from '../utils/is-hex-string.js'; -import * as csv from 'csv'; -import { isObjectEmpty } from '../../../helpers/is-object-empty.js'; -import { FilteringFieldsDs } from '../table-datastructures.js'; -import { NonAvailableInFreePlanException } from '../../../exceptions/custom-exceptions/non-available-in-free-plan-exception.js'; -import { slackPostMessage } from '../../../helpers/index.js'; -import { buildDAOsTableSettingsDs } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/table-settings.ds.builder.js'; +import { IExportCSVFromTable } from './table-use-cases.interface.js'; @Injectable() export class ExportCSVFromTableUseCase - extends AbstractUseCase - implements IExportCSVFromTable + extends AbstractUseCase + implements IExportCSVFromTable { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private tableLogsService: TableLogsService, - ) { - super(); - } - - protected async implementation(inputData: GetTableRowsDs): Promise { - // eslint-disable-next-line prefer-const - let { connectionId, masterPwd, page, perPage, query, searchingFieldValue, tableName, userId, filters } = inputData; - const connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, masterPwd); - if (!connection) { - throw new HttpException( - { - message: Messages.CONNECTION_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - - if (connection.is_frozen) { - throw new NonAvailableInFreePlanException(Messages.CONNECTION_IS_FROZEN); - } - - let operationResult = OperationResultStatusEnum.unknown; - - try { - const dao = getDataAccessObject(connection); - - let userEmail: string; - if (isConnectionTypeAgent(connection.type)) { - userEmail = await this._dbContext.userRepository.getUserEmailOrReturnNull(userId); - } - - // eslint-disable-next-line prefer-const - let [tableSettings, tableStructure, personalTableSettings] = await Promise.all([ - this._dbContext.tableSettingsRepository.findTableSettings(connectionId, tableName), - dao.getTableStructure(tableName, userEmail), - this._dbContext.personalTableSettingsRepository.findUserTableSettings(userId, connectionId, tableName), - ]); - if (!tableSettings) { - tableSettings = {} as any; - } - - if (tableSettings.allow_csv_export === false) { - throw new HttpException( - { - message: Messages.CSV_EXPORT_DISABLED, - }, - HttpStatus.BAD_REQUEST, - ); - } - - const filteringFields: Array = isObjectEmpty(filters) - ? findFilteringFieldsUtil(query, tableStructure) - : parseFilteringFieldsFromBodyData(filters, tableStructure); - - const orderingField = findOrderingFieldUtil(query, tableStructure, tableSettings); - - const builtDAOsTableSettings = buildDAOsTableSettingsDs(tableSettings, personalTableSettings); - - if (orderingField) { - builtDAOsTableSettings.ordering_field = orderingField.field; - builtDAOsTableSettings.ordering = orderingField.value; - } - - if (isHexString(searchingFieldValue)) { - searchingFieldValue = hexToBinary(searchingFieldValue) as any; - tableSettings.search_fields = tableStructure - .filter((field) => isBinary(field.data_type)) - .map((field) => field.column_name); - } - - const rowsStream = await dao.getTableRowsStream( - tableName, - builtDAOsTableSettings, - page, - perPage, - searchingFieldValue, - filteringFields, - ); - - operationResult = OperationResultStatusEnum.successfully; - - //todo: rework as streams when node oracle driver will support it correctly - //todo: agent return data as array of table rows, not as stream, because we cant - //todo: transfer data as a stream from clint to server - if ( - connection.type === 'oracledb' || - connection.type === 'ibmdb2' || - connection.type === 'mongodb' || - connection.type === 'dynamodb' || - connection.type === 'elasticsearch' || - connection.type === 'redis' || - isConnectionTypeAgent(connection.type) - ) { - return new StreamableFile(csv.stringify(rowsStream as any, { header: true })); - } - return new StreamableFile(rowsStream.pipe(csv.stringify({ header: true }))); - } catch (error) { - operationResult = OperationResultStatusEnum.unsuccessfully; - if (error instanceof HttpException) { - throw error; - } - // todo: temporary debug log - await slackPostMessage(` + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private tableLogsService: TableLogsService, + ) { + super(); + } + + protected async implementation(inputData: GetTableRowsDs): Promise { + // eslint-disable-next-line prefer-const + let { connectionId, masterPwd, page, perPage, query, searchingFieldValue, tableName, userId, filters } = inputData; + const connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, masterPwd); + if (!connection) { + throw new HttpException( + { + message: Messages.CONNECTION_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + + if (connection.is_frozen) { + throw new NonAvailableInFreePlanException(Messages.CONNECTION_IS_FROZEN); + } + + let operationResult = OperationResultStatusEnum.unknown; + + try { + const dao = getDataAccessObject(connection); + + let userEmail: string; + if (isConnectionTypeAgent(connection.type)) { + userEmail = await this._dbContext.userRepository.getUserEmailOrReturnNull(userId); + } + + // eslint-disable-next-line prefer-const + let [tableSettings, tableStructure, personalTableSettings] = await Promise.all([ + this._dbContext.tableSettingsRepository.findTableSettings(connectionId, tableName), + dao.getTableStructure(tableName, userEmail), + this._dbContext.personalTableSettingsRepository.findUserTableSettings(userId, connectionId, tableName), + ]); + if (!tableSettings) { + tableSettings = {} as any; + } + + if (tableSettings.allow_csv_export === false) { + throw new HttpException( + { + message: Messages.CSV_EXPORT_DISABLED, + }, + HttpStatus.BAD_REQUEST, + ); + } + + const filteringFields: Array = isObjectEmpty(filters) + ? findFilteringFieldsUtil(query, tableStructure) + : parseFilteringFieldsFromBodyData(filters, tableStructure); + + const orderingField = findOrderingFieldUtil(query, tableStructure, tableSettings); + + const builtDAOsTableSettings = buildDAOsTableSettingsDs(tableSettings, personalTableSettings); + + if (orderingField) { + builtDAOsTableSettings.ordering_field = orderingField.field; + builtDAOsTableSettings.ordering = orderingField.value; + } + + if (isHexString(searchingFieldValue)) { + searchingFieldValue = hexToBinary(searchingFieldValue) as any; + tableSettings.search_fields = tableStructure + .filter((field) => isBinary(field.data_type)) + .map((field) => field.column_name); + } + + const rowsStream = await dao.getTableRowsStream( + tableName, + builtDAOsTableSettings, + page, + perPage, + searchingFieldValue, + filteringFields, + ); + + operationResult = OperationResultStatusEnum.successfully; + + //todo: rework as streams when node oracle driver will support it correctly + //todo: agent return data as array of table rows, not as stream, because we cant + //todo: transfer data as a stream from clint to server + if ( + connection.type === 'oracledb' || + connection.type === 'ibmdb2' || + connection.type === 'mongodb' || + connection.type === 'dynamodb' || + connection.type === 'elasticsearch' || + connection.type === 'redis' || + isConnectionTypeAgent(connection.type) + ) { + return new StreamableFile(csv.stringify(rowsStream as any, { header: true })); + } + return new StreamableFile(rowsStream.pipe(csv.stringify({ header: true }))); + } catch (error) { + operationResult = OperationResultStatusEnum.unsuccessfully; + if (error instanceof HttpException) { + throw error; + } + // todo: temporary debug log + await slackPostMessage(` CSV Export Failed with error: ${error.message}\n Connection type: ${connection.type}\n SSH Option: ${connection.ssh}\n SSL Option: ${connection.ssl}\n `); - throw new HttpException( - { - message: Messages.CSV_EXPORT_FAILED, - originalMessage: error.message, - }, - HttpStatus.INTERNAL_SERVER_ERROR, - ); - } finally { - const logRecord = { - table_name: tableName, - userId: userId, - connection: connection, - operationType: LogOperationTypeEnum.exportRows, - operationStatusResult: operationResult, - }; - await this.tableLogsService.crateAndSaveNewLogUtil(logRecord); - } - } + throw new HttpException( + { + message: Messages.CSV_EXPORT_FAILED, + originalMessage: error.message, + }, + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } finally { + const logRecord = { + table_name: tableName, + userId: userId, + connection: connection, + operationType: LogOperationTypeEnum.exportRows, + operationStatusResult: operationResult, + }; + await this.tableLogsService.crateAndSaveNewLogUtil(logRecord); + } + } } diff --git a/backend/src/entities/table/use-cases/find-tables-in-connection-v2.use.case.ts b/backend/src/entities/table/use-cases/find-tables-in-connection-v2.use.case.ts index f15f3558f..655fa1321 100644 --- a/backend/src/entities/table/use-cases/find-tables-in-connection-v2.use.case.ts +++ b/backend/src/entities/table/use-cases/find-tables-in-connection-v2.use.case.ts @@ -1,7 +1,7 @@ import { HttpException, HttpStatus, Inject, Injectable, Scope } from '@nestjs/common'; import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; -import { TableStructureDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/table-structure.ds.js'; import { TableDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/table.ds.js'; +import { TableStructureDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/table-structure.ds.js'; import * as Sentry from '@sentry/node'; import PQueue from 'p-queue'; import AbstractUseCase from '../../../common/abstract-use.case.js'; @@ -28,280 +28,280 @@ import { IFindTablesInConnectionV2 } from './table-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class FindTablesInConnectionV2UseCase - extends AbstractUseCase - implements IFindTablesInConnectionV2 + extends AbstractUseCase + implements IFindTablesInConnectionV2 { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private amplitudeService: AmplitudeService, - private readonly logger: WinstonLogger, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private amplitudeService: AmplitudeService, + private readonly logger: WinstonLogger, + ) { + super(); + } - protected async implementation(inputData: FindTablesDs): Promise { - const { connectionId, hiddenTablesOption, masterPwd, userId } = inputData; - let connection: ConnectionEntity; - try { - connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, masterPwd); - } catch (error) { - if (error.message === Messages.MASTER_PASSWORD_MISSING) { - throw new HttpException( - { - message: Messages.MASTER_PASSWORD_MISSING, - type: 'no_master_key', - }, - HttpStatus.BAD_REQUEST, - ); - } - if (error.message === Messages.MASTER_PASSWORD_INCORRECT) { - throw new HttpException( - { - message: Messages.MASTER_PASSWORD_INCORRECT, - type: 'invalid_master_key', - }, - HttpStatus.BAD_REQUEST, - ); - } - } - if (!connection) { - throw new HttpException( - { - message: Messages.CONNECTION_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - const dao = getDataAccessObject(connection); - let userEmail: string; - let operationResult = false; - if (isConnectionTypeAgent(connection.type)) { - userEmail = await this._dbContext.userRepository.getUserEmailOrReturnNull(userId); - } - let tables: Array; - try { - tables = await dao.getTablesFromDB(userEmail); - operationResult = true; - } catch (e) { - operationResult = false; - Sentry.captureException(e); - throw new UnknownSQLException(e.message, ExceptionOperations.FAILED_TO_GET_TABLES); - } finally { - if (!connection.isTestConnection && tables && tables.length) { - this.logger.log({ - tables: tables.map((table) => table.tableName), - connectionId: connectionId, - connectionType: connection.type, - }); - } - const isTest = isTestConnectionUtil(connection); - await this.amplitudeService.formAndSendLogRecord( - isTest ? AmplitudeEventTypeEnum.tableListReceivedTest : AmplitudeEventTypeEnum.tableListReceived, - userId, - { tablesCount: tables?.length ? tables.length : 0 }, - ); - if ( - connection.saved_table_info === 0 && - !connection.isTestConnection && - operationResult && - process.env.NODE_ENV !== 'test' - ) { - this.saveTableInfoInDatabase(connection.id, userId, tables, masterPwd); - } - } - const tablesWithPermissions = await this.getUserPermissionsForAvailableTables(userId, connectionId, tables); - const foundConnectionProperties = - await this._dbContext.connectionPropertiesRepository.findConnectionPropertiesWithTablesCategories(connectionId); - let tablesRO = await this.addDisplayNamesForTables(connectionId, tablesWithPermissions); - if (foundConnectionProperties && foundConnectionProperties.hidden_tables.length > 0) { - if (!hiddenTablesOption) { - tablesRO = tablesRO.filter((tableRO) => { - return !foundConnectionProperties.hidden_tables.includes(tableRO.table); - }); - } else { - const userConnectionEdit = await this._dbContext.userAccessRepository.checkUserConnectionEdit( - userId, - connectionId, - ); - if (!userConnectionEdit) { - throw new HttpException( - { - message: Messages.DONT_HAVE_PERMISSIONS, - }, - HttpStatus.FORBIDDEN, - ); - } - } - } + protected async implementation(inputData: FindTablesDs): Promise { + const { connectionId, hiddenTablesOption, masterPwd, userId } = inputData; + let connection: ConnectionEntity; + try { + connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, masterPwd); + } catch (error) { + if (error.message === Messages.MASTER_PASSWORD_MISSING) { + throw new HttpException( + { + message: Messages.MASTER_PASSWORD_MISSING, + type: 'no_master_key', + }, + HttpStatus.BAD_REQUEST, + ); + } + if (error.message === Messages.MASTER_PASSWORD_INCORRECT) { + throw new HttpException( + { + message: Messages.MASTER_PASSWORD_INCORRECT, + type: 'invalid_master_key', + }, + HttpStatus.BAD_REQUEST, + ); + } + } + if (!connection) { + throw new HttpException( + { + message: Messages.CONNECTION_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + const dao = getDataAccessObject(connection); + let userEmail: string; + let operationResult = false; + if (isConnectionTypeAgent(connection.type)) { + userEmail = await this._dbContext.userRepository.getUserEmailOrReturnNull(userId); + } + let tables: Array; + try { + tables = await dao.getTablesFromDB(userEmail); + operationResult = true; + } catch (e) { + operationResult = false; + Sentry.captureException(e); + throw new UnknownSQLException(e.message, ExceptionOperations.FAILED_TO_GET_TABLES); + } finally { + if (!connection.isTestConnection && tables && tables.length) { + this.logger.log({ + tables: tables.map((table) => table.tableName), + connectionId: connectionId, + connectionType: connection.type, + }); + } + const isTest = isTestConnectionUtil(connection); + await this.amplitudeService.formAndSendLogRecord( + isTest ? AmplitudeEventTypeEnum.tableListReceivedTest : AmplitudeEventTypeEnum.tableListReceived, + userId, + { tablesCount: tables?.length ? tables.length : 0 }, + ); + if ( + connection.saved_table_info === 0 && + !connection.isTestConnection && + operationResult && + process.env.NODE_ENV !== 'test' + ) { + this.saveTableInfoInDatabase(connection.id, userId, tables, masterPwd); + } + } + const tablesWithPermissions = await this.getUserPermissionsForAvailableTables(userId, connectionId, tables); + const foundConnectionProperties = + await this._dbContext.connectionPropertiesRepository.findConnectionPropertiesWithTablesCategories(connectionId); + let tablesRO = await this.addDisplayNamesForTables(connectionId, tablesWithPermissions); + if (foundConnectionProperties && foundConnectionProperties.hidden_tables.length > 0) { + if (!hiddenTablesOption) { + tablesRO = tablesRO.filter((tableRO) => { + return !foundConnectionProperties.hidden_tables.includes(tableRO.table); + }); + } else { + const userConnectionEdit = await this._dbContext.userAccessRepository.checkUserConnectionEdit( + userId, + connectionId, + ); + if (!userConnectionEdit) { + throw new HttpException( + { + message: Messages.DONT_HAVE_PERMISSIONS, + }, + HttpStatus.FORBIDDEN, + ); + } + } + } - const sortedTables = tablesRO.sort((tableRO1, tableRO2) => { - const name1 = tableRO1.display_name || tableRO1.table; - const name2 = tableRO2.display_name || tableRO2.table; - return name1.localeCompare(name2); - }); + const sortedTables = tablesRO.sort((tableRO1, tableRO2) => { + const name1 = tableRO1.display_name || tableRO1.table; + const name2 = tableRO2.display_name || tableRO2.table; + return name1.localeCompare(name2); + }); - const tableCategories = foundConnectionProperties?.table_categories || []; + const tableCategories = foundConnectionProperties?.table_categories || []; - const responseObject: FoundTablesWithCategoriesDS = { - tables: sortedTables, - table_categories: tableCategories.map(({ category_name, category_id, tables, category_color }) => ({ - category_name, - category_id, - tables, - category_color, - })), - }; - return responseObject; - } + const responseObject: FoundTablesWithCategoriesDS = { + tables: sortedTables, + table_categories: tableCategories.map(({ category_name, category_id, tables, category_color }) => ({ + category_name, + category_id, + tables, + category_color, + })), + }; + return responseObject; + } - private async addDisplayNamesForTables( - connectionId: string, - tablesObjArr: Array, - ): Promise> { - const tableSettings = await this._dbContext.tableSettingsRepository.findTableSettingsInConnectionPure(connectionId); - return tablesObjArr.map((tableObj: ITableAndViewPermissionData) => { - const foundTableSettings = - tableSettings[ - tableSettings.findIndex((el: TableSettingsEntity) => { - return el.table_name === tableObj.tableName; - }) - ]; - const displayName = foundTableSettings ? foundTableSettings.display_name : undefined; - const icon = foundTableSettings ? foundTableSettings.icon : undefined; - return { - table: tableObj.tableName, - isView: tableObj.isView || false, - permissions: tableObj.accessLevel, - display_name: displayName, - icon: icon, - }; - }); - } + private async addDisplayNamesForTables( + connectionId: string, + tablesObjArr: Array, + ): Promise> { + const tableSettings = await this._dbContext.tableSettingsRepository.findTableSettingsInConnectionPure(connectionId); + return tablesObjArr.map((tableObj: ITableAndViewPermissionData) => { + const foundTableSettings = + tableSettings[ + tableSettings.findIndex((el: TableSettingsEntity) => { + return el.table_name === tableObj.tableName; + }) + ]; + const displayName = foundTableSettings ? foundTableSettings.display_name : undefined; + const icon = foundTableSettings ? foundTableSettings.icon : undefined; + return { + table: tableObj.tableName, + isView: tableObj.isView || false, + permissions: tableObj.accessLevel, + display_name: displayName, + icon: icon, + }; + }); + } - private async getUserPermissionsForAvailableTables( - userId: string, - connectionId: string, - tables: Array, - ): Promise> { - const connectionEdit = await this._dbContext.userAccessRepository.checkUserConnectionEdit(userId, connectionId); - if (connectionEdit) { - return tables.map((table) => { - return { - tableName: table.tableName, - isView: table.isView, - accessLevel: { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: true, - }, - }; - }); - } + private async getUserPermissionsForAvailableTables( + userId: string, + connectionId: string, + tables: Array, + ): Promise> { + const connectionEdit = await this._dbContext.userAccessRepository.checkUserConnectionEdit(userId, connectionId); + if (connectionEdit) { + return tables.map((table) => { + return { + tableName: table.tableName, + isView: table.isView, + accessLevel: { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: true, + }, + }; + }); + } - const allTablePermissions = - await this._dbContext.permissionRepository.getAllUserPermissionsForAllTablesInConnection(userId, connectionId); - const tablesAndAccessLevels = {}; - tables.map((table) => { - if (table.tableName !== '__proto__') { - tablesAndAccessLevels[table.tableName] = []; - } - }); - tables.map((table) => { - allTablePermissions.map((permission) => { - if ( - permission.tableName === table.tableName && - isObjectPropertyExists(tablesAndAccessLevels, table.tableName) - ) { - tablesAndAccessLevels[table.tableName].push(permission.accessLevel); - } - }); - }); - const tablesWithPermissions: Array = []; - for (const key in tablesAndAccessLevels) { - // eslint-disable-next-line security/detect-object-injection - const addPermission = tablesAndAccessLevels[key].includes(AccessLevelEnum.add); - // eslint-disable-next-line security/detect-object-injection - const deletePermission = tablesAndAccessLevels[key].includes(AccessLevelEnum.delete); - // eslint-disable-next-line security/detect-object-injection - const editPermission = tablesAndAccessLevels[key].includes(AccessLevelEnum.edit); + const allTablePermissions = + await this._dbContext.permissionRepository.getAllUserPermissionsForAllTablesInConnection(userId, connectionId); + const tablesAndAccessLevels = {}; + tables.map((table) => { + if (table.tableName !== '__proto__') { + tablesAndAccessLevels[table.tableName] = []; + } + }); + tables.map((table) => { + allTablePermissions.map((permission) => { + if ( + permission.tableName === table.tableName && + isObjectPropertyExists(tablesAndAccessLevels, table.tableName) + ) { + tablesAndAccessLevels[table.tableName].push(permission.accessLevel); + } + }); + }); + const tablesWithPermissions: Array = []; + for (const key in tablesAndAccessLevels) { + // eslint-disable-next-line security/detect-object-injection + const addPermission = tablesAndAccessLevels[key].includes(AccessLevelEnum.add); + // eslint-disable-next-line security/detect-object-injection + const deletePermission = tablesAndAccessLevels[key].includes(AccessLevelEnum.delete); + // eslint-disable-next-line security/detect-object-injection + const editPermission = tablesAndAccessLevels[key].includes(AccessLevelEnum.edit); - const readOnly = !(addPermission || deletePermission || editPermission); - tablesWithPermissions.push({ - tableName: key, - isView: tables.find((table) => table.tableName === key).isView, - accessLevel: { - // eslint-disable-next-line security/detect-object-injection - visibility: tablesAndAccessLevels[key].includes(AccessLevelEnum.visibility), - // eslint-disable-next-line security/detect-object-injection - readonly: tablesAndAccessLevels[key].includes(AccessLevelEnum.readonly) && !readOnly, - add: addPermission, - delete: deletePermission, - edit: editPermission, - }, - }); - } - return tablesWithPermissions.filter((tableWithPermission: ITableAndViewPermissionData) => { - return !!tableWithPermission.accessLevel.visibility; - }); - } + const readOnly = !(addPermission || deletePermission || editPermission); + tablesWithPermissions.push({ + tableName: key, + isView: tables.find((table) => table.tableName === key).isView, + accessLevel: { + // eslint-disable-next-line security/detect-object-injection + visibility: tablesAndAccessLevels[key].includes(AccessLevelEnum.visibility), + // eslint-disable-next-line security/detect-object-injection + readonly: tablesAndAccessLevels[key].includes(AccessLevelEnum.readonly) && !readOnly, + add: addPermission, + delete: deletePermission, + edit: editPermission, + }, + }); + } + return tablesWithPermissions.filter((tableWithPermission: ITableAndViewPermissionData) => { + return !!tableWithPermission.accessLevel.visibility; + }); + } - private async saveTableInfoInDatabase( - connectionId: string, - _userId: string, - tables: Array, - masterPwd: string, - ): Promise { - try { - const foundConnection = await this._dbContext.connectionRepository.findOne({ where: { id: connectionId } }); - if (!foundConnection) { - return; - } - const decryptedConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( - connectionId, - masterPwd, - ); - const tableNames: Array = tables.map((table) => table.tableName); - const queue = new PQueue({ concurrency: 2 }); - const dao = getDataAccessObject(decryptedConnection); - const tablesStructures: Array<{ - tableName: string; - structure: Array; - }> = (await Promise.all( - tableNames.map(async (tableName) => { - return await queue.add(async () => { - const structure = await dao.getTableStructure(tableName, undefined); - return { - tableName: tableName, - structure: structure, - }; - }); - }), - )) as Array<{ - tableName: string; - structure: Array; - }>; - foundConnection.tables_info = (await Promise.all( - tablesStructures.map(async (tableStructure) => { - return await queue.add(async () => { - const newTableInfo = buildTableInfoEntity(tableStructure.tableName, foundConnection); - const savedTableInfo = await this._dbContext.tableInfoRepository.save(newTableInfo); - const newTableFieldsInfos = tableStructure.structure.map((el) => - buildTableFieldInfoEntity(el, savedTableInfo), - ); - newTableInfo.table_fields_info = await this._dbContext.tableFieldInfoRepository.save(newTableFieldsInfos); - await this._dbContext.tableInfoRepository.save(newTableInfo); - return newTableInfo; - }); - }), - )) as Array; - foundConnection.saved_table_info = ++foundConnection.saved_table_info; - await this._dbContext.connectionRepository.saveUpdatedConnection(foundConnection); - } catch (e) { - Sentry.captureException(e); - console.error(e); - } - } + private async saveTableInfoInDatabase( + connectionId: string, + _userId: string, + tables: Array, + masterPwd: string, + ): Promise { + try { + const foundConnection = await this._dbContext.connectionRepository.findOne({ where: { id: connectionId } }); + if (!foundConnection) { + return; + } + const decryptedConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( + connectionId, + masterPwd, + ); + const tableNames: Array = tables.map((table) => table.tableName); + const queue = new PQueue({ concurrency: 2 }); + const dao = getDataAccessObject(decryptedConnection); + const tablesStructures: Array<{ + tableName: string; + structure: Array; + }> = (await Promise.all( + tableNames.map(async (tableName) => { + return await queue.add(async () => { + const structure = await dao.getTableStructure(tableName, undefined); + return { + tableName: tableName, + structure: structure, + }; + }); + }), + )) as Array<{ + tableName: string; + structure: Array; + }>; + foundConnection.tables_info = (await Promise.all( + tablesStructures.map(async (tableStructure) => { + return await queue.add(async () => { + const newTableInfo = buildTableInfoEntity(tableStructure.tableName, foundConnection); + const savedTableInfo = await this._dbContext.tableInfoRepository.save(newTableInfo); + const newTableFieldsInfos = tableStructure.structure.map((el) => + buildTableFieldInfoEntity(el, savedTableInfo), + ); + newTableInfo.table_fields_info = await this._dbContext.tableFieldInfoRepository.save(newTableFieldsInfos); + await this._dbContext.tableInfoRepository.save(newTableInfo); + return newTableInfo; + }); + }), + )) as Array; + foundConnection.saved_table_info = ++foundConnection.saved_table_info; + await this._dbContext.connectionRepository.saveUpdatedConnection(foundConnection); + } catch (e) { + Sentry.captureException(e); + console.error(e); + } + } } diff --git a/backend/src/entities/table/use-cases/find-tables-in-connection.use.case.ts b/backend/src/entities/table/use-cases/find-tables-in-connection.use.case.ts index 9b76f5c48..3433046de 100644 --- a/backend/src/entities/table/use-cases/find-tables-in-connection.use.case.ts +++ b/backend/src/entities/table/use-cases/find-tables-in-connection.use.case.ts @@ -1,7 +1,7 @@ import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; -import { TableStructureDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/table-structure.ds.js'; import { TableDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/table.ds.js'; +import { TableStructureDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/table-structure.ds.js'; import * as Sentry from '@sentry/node'; import PQueue from 'p-queue'; import AbstractUseCase from '../../../common/abstract-use.case.js'; @@ -16,6 +16,7 @@ import { isObjectPropertyExists } from '../../../helpers/validators/is-object-pr import { AmplitudeService } from '../../amplitude/amplitude.service.js'; import { ConnectionEntity } from '../../connection/connection.entity.js'; import { isTestConnectionUtil } from '../../connection/utils/is-test-connection-util.js'; +import { WinstonLogger } from '../../logging/winston-logger.js'; import { ITableAndViewPermissionData } from '../../permission/permission.interface.js'; import { TableInfoEntity } from '../../table-info/table-info.entity.js'; import { TableSettingsEntity } from '../../table-settings/common-table-settings/table-settings.entity.js'; @@ -23,281 +24,280 @@ import { FindTablesDs } from '../application/data-structures/find-tables.ds.js'; import { FoundTableDs } from '../application/data-structures/found-table.ds.js'; import { buildTableFieldInfoEntity, buildTableInfoEntity } from '../utils/save-tables-info-in-database.util.js'; import { IFindTablesInConnection } from './table-use-cases.interface.js'; -import { WinstonLogger } from '../../logging/winston-logger.js'; @Injectable() export class FindTablesInConnectionUseCase - extends AbstractUseCase> - implements IFindTablesInConnection + extends AbstractUseCase> + implements IFindTablesInConnection { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private amplitudeService: AmplitudeService, - private readonly logger: WinstonLogger, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private amplitudeService: AmplitudeService, + private readonly logger: WinstonLogger, + ) { + super(); + } - protected async implementation(inputData: FindTablesDs): Promise> { - const { connectionId, hiddenTablesOption, masterPwd, userId } = inputData; - let connection: ConnectionEntity; - try { - connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, masterPwd); - } catch (error) { - if (error.message === Messages.MASTER_PASSWORD_MISSING) { - throw new HttpException( - { - message: Messages.MASTER_PASSWORD_MISSING, - type: 'no_master_key', - }, - HttpStatus.BAD_REQUEST, - ); - } - if (error.message === Messages.MASTER_PASSWORD_INCORRECT) { - throw new HttpException( - { - message: Messages.MASTER_PASSWORD_INCORRECT, - type: 'invalid_master_key', - }, - HttpStatus.BAD_REQUEST, - ); - } - } - if (!connection) { - throw new HttpException( - { - message: Messages.CONNECTION_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - const dao = getDataAccessObject(connection); - let userEmail: string; - let operationResult = false; - if (isConnectionTypeAgent(connection.type)) { - userEmail = await this._dbContext.userRepository.getUserEmailOrReturnNull(userId); - } - let tables: Array; - try { - tables = await dao.getTablesFromDB(userEmail); - operationResult = true; - } catch (e) { - operationResult = false; - Sentry.captureException(e); - throw new UnknownSQLException(e.message, ExceptionOperations.FAILED_TO_GET_TABLES); - } finally { - if (!connection.isTestConnection && tables && tables.length) { - this.logger.log({ - tables: tables.map((table) => table.tableName), - connectionId: connectionId, - connectionType: connection.type, - }); - } - const isTest = isTestConnectionUtil(connection); - await this.amplitudeService.formAndSendLogRecord( - isTest ? AmplitudeEventTypeEnum.tableListReceivedTest : AmplitudeEventTypeEnum.tableListReceived, - userId, - { tablesCount: tables?.length ? tables.length : 0 }, - ); - if ( - connection.saved_table_info === 0 && - !connection.isTestConnection && - operationResult && - process.env.NODE_ENV !== 'test' - ) { - this.saveTableInfoInDatabase(connection.id, userId, tables, masterPwd); - } - } - const tablesWithPermissions = await this.getUserPermissionsForAvailableTables(userId, connectionId, tables); - const excludedTables = await this._dbContext.connectionPropertiesRepository.findConnectionProperties(connectionId); - let tablesRO = await this.addDisplayNamesForTables(connectionId, tablesWithPermissions); - if (excludedTables?.hidden_tables?.length) { - if (!hiddenTablesOption) { - tablesRO = tablesRO.filter((tableRO) => { - return !excludedTables.hidden_tables.includes(tableRO.table); - }); - } else { - const userConnectionEdit = await this._dbContext.userAccessRepository.checkUserConnectionEdit( - userId, - connectionId, - ); - if (!userConnectionEdit) { - throw new HttpException( - { - message: Messages.DONT_HAVE_PERMISSIONS, - }, - HttpStatus.FORBIDDEN, - ); - } - } - } - return tablesRO.sort((tableRO1, tableRO2) => { - const display_name1 = tableRO1.display_name; - const display_name2 = tableRO2.display_name; - if (display_name1 && display_name2) { - return display_name1.localeCompare(display_name2); - } - if (!display_name1 && !display_name2) { - return tableRO1.table.localeCompare(tableRO2.table); - } - if (!display_name1 && display_name2) { - return tableRO1.table.localeCompare(display_name2); - } - if (display_name1 && !display_name2) { - return display_name1.localeCompare(tableRO2.table); - } - return 0; - }); - } + protected async implementation(inputData: FindTablesDs): Promise> { + const { connectionId, hiddenTablesOption, masterPwd, userId } = inputData; + let connection: ConnectionEntity; + try { + connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, masterPwd); + } catch (error) { + if (error.message === Messages.MASTER_PASSWORD_MISSING) { + throw new HttpException( + { + message: Messages.MASTER_PASSWORD_MISSING, + type: 'no_master_key', + }, + HttpStatus.BAD_REQUEST, + ); + } + if (error.message === Messages.MASTER_PASSWORD_INCORRECT) { + throw new HttpException( + { + message: Messages.MASTER_PASSWORD_INCORRECT, + type: 'invalid_master_key', + }, + HttpStatus.BAD_REQUEST, + ); + } + } + if (!connection) { + throw new HttpException( + { + message: Messages.CONNECTION_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + const dao = getDataAccessObject(connection); + let userEmail: string; + let operationResult = false; + if (isConnectionTypeAgent(connection.type)) { + userEmail = await this._dbContext.userRepository.getUserEmailOrReturnNull(userId); + } + let tables: Array; + try { + tables = await dao.getTablesFromDB(userEmail); + operationResult = true; + } catch (e) { + operationResult = false; + Sentry.captureException(e); + throw new UnknownSQLException(e.message, ExceptionOperations.FAILED_TO_GET_TABLES); + } finally { + if (!connection.isTestConnection && tables && tables.length) { + this.logger.log({ + tables: tables.map((table) => table.tableName), + connectionId: connectionId, + connectionType: connection.type, + }); + } + const isTest = isTestConnectionUtil(connection); + await this.amplitudeService.formAndSendLogRecord( + isTest ? AmplitudeEventTypeEnum.tableListReceivedTest : AmplitudeEventTypeEnum.tableListReceived, + userId, + { tablesCount: tables?.length ? tables.length : 0 }, + ); + if ( + connection.saved_table_info === 0 && + !connection.isTestConnection && + operationResult && + process.env.NODE_ENV !== 'test' + ) { + this.saveTableInfoInDatabase(connection.id, userId, tables, masterPwd); + } + } + const tablesWithPermissions = await this.getUserPermissionsForAvailableTables(userId, connectionId, tables); + const excludedTables = await this._dbContext.connectionPropertiesRepository.findConnectionProperties(connectionId); + let tablesRO = await this.addDisplayNamesForTables(connectionId, tablesWithPermissions); + if (excludedTables?.hidden_tables?.length) { + if (!hiddenTablesOption) { + tablesRO = tablesRO.filter((tableRO) => { + return !excludedTables.hidden_tables.includes(tableRO.table); + }); + } else { + const userConnectionEdit = await this._dbContext.userAccessRepository.checkUserConnectionEdit( + userId, + connectionId, + ); + if (!userConnectionEdit) { + throw new HttpException( + { + message: Messages.DONT_HAVE_PERMISSIONS, + }, + HttpStatus.FORBIDDEN, + ); + } + } + } + return tablesRO.sort((tableRO1, tableRO2) => { + const display_name1 = tableRO1.display_name; + const display_name2 = tableRO2.display_name; + if (display_name1 && display_name2) { + return display_name1.localeCompare(display_name2); + } + if (!display_name1 && !display_name2) { + return tableRO1.table.localeCompare(tableRO2.table); + } + if (!display_name1 && display_name2) { + return tableRO1.table.localeCompare(display_name2); + } + if (display_name1 && !display_name2) { + return display_name1.localeCompare(tableRO2.table); + } + return 0; + }); + } - private async addDisplayNamesForTables( - connectionId: string, - tablesObjArr: Array, - ): Promise> { - const tableSettings = await this._dbContext.tableSettingsRepository.findTableSettingsInConnectionPure(connectionId); - return tablesObjArr.map((tableObj: ITableAndViewPermissionData) => { - const foundTableSettings = - tableSettings[ - tableSettings.findIndex((el: TableSettingsEntity) => { - return el.table_name === tableObj.tableName; - }) - ]; - const displayName = foundTableSettings ? foundTableSettings.display_name : undefined; - const icon = foundTableSettings ? foundTableSettings.icon : undefined; - return { - table: tableObj.tableName, - isView: tableObj.isView || false, - permissions: tableObj.accessLevel, - display_name: displayName, - icon: icon, - }; - }); - } + private async addDisplayNamesForTables( + connectionId: string, + tablesObjArr: Array, + ): Promise> { + const tableSettings = await this._dbContext.tableSettingsRepository.findTableSettingsInConnectionPure(connectionId); + return tablesObjArr.map((tableObj: ITableAndViewPermissionData) => { + const foundTableSettings = + tableSettings[ + tableSettings.findIndex((el: TableSettingsEntity) => { + return el.table_name === tableObj.tableName; + }) + ]; + const displayName = foundTableSettings ? foundTableSettings.display_name : undefined; + const icon = foundTableSettings ? foundTableSettings.icon : undefined; + return { + table: tableObj.tableName, + isView: tableObj.isView || false, + permissions: tableObj.accessLevel, + display_name: displayName, + icon: icon, + }; + }); + } - private async getUserPermissionsForAvailableTables( - userId: string, - connectionId: string, - tables: Array, - ): Promise> { - const connectionEdit = await this._dbContext.userAccessRepository.checkUserConnectionEdit(userId, connectionId); - if (connectionEdit) { - return tables.map((table) => { - return { - tableName: table.tableName, - isView: table.isView, - accessLevel: { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: true, - }, - }; - }); - } + private async getUserPermissionsForAvailableTables( + userId: string, + connectionId: string, + tables: Array, + ): Promise> { + const connectionEdit = await this._dbContext.userAccessRepository.checkUserConnectionEdit(userId, connectionId); + if (connectionEdit) { + return tables.map((table) => { + return { + tableName: table.tableName, + isView: table.isView, + accessLevel: { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: true, + }, + }; + }); + } - const allTablePermissions = - await this._dbContext.permissionRepository.getAllUserPermissionsForAllTablesInConnection(userId, connectionId); - const tablesAndAccessLevels = {}; - tables.map((table) => { - if (table.tableName !== '__proto__') { - tablesAndAccessLevels[table.tableName] = []; - } - }); - tables.map((table) => { - allTablePermissions.map((permission) => { - if ( - permission.tableName === table.tableName && - isObjectPropertyExists(tablesAndAccessLevels, table.tableName) - ) { - tablesAndAccessLevels[table.tableName].push(permission.accessLevel); - } - }); - }); - const tablesWithPermissions: Array = []; - for (const key in tablesAndAccessLevels) { - // eslint-disable-next-line security/detect-object-injection - const addPermission = tablesAndAccessLevels[key].includes(AccessLevelEnum.add); - // eslint-disable-next-line security/detect-object-injection - const deletePermission = tablesAndAccessLevels[key].includes(AccessLevelEnum.delete); - // eslint-disable-next-line security/detect-object-injection - const editPermission = tablesAndAccessLevels[key].includes(AccessLevelEnum.edit); + const allTablePermissions = + await this._dbContext.permissionRepository.getAllUserPermissionsForAllTablesInConnection(userId, connectionId); + const tablesAndAccessLevels = {}; + tables.map((table) => { + if (table.tableName !== '__proto__') { + tablesAndAccessLevels[table.tableName] = []; + } + }); + tables.map((table) => { + allTablePermissions.map((permission) => { + if ( + permission.tableName === table.tableName && + isObjectPropertyExists(tablesAndAccessLevels, table.tableName) + ) { + tablesAndAccessLevels[table.tableName].push(permission.accessLevel); + } + }); + }); + const tablesWithPermissions: Array = []; + for (const key in tablesAndAccessLevels) { + // eslint-disable-next-line security/detect-object-injection + const addPermission = tablesAndAccessLevels[key].includes(AccessLevelEnum.add); + // eslint-disable-next-line security/detect-object-injection + const deletePermission = tablesAndAccessLevels[key].includes(AccessLevelEnum.delete); + // eslint-disable-next-line security/detect-object-injection + const editPermission = tablesAndAccessLevels[key].includes(AccessLevelEnum.edit); - const readOnly = !(addPermission || deletePermission || editPermission); - tablesWithPermissions.push({ - tableName: key, - isView: tables.find((table) => table.tableName === key).isView, - accessLevel: { - // eslint-disable-next-line security/detect-object-injection - visibility: tablesAndAccessLevels[key].includes(AccessLevelEnum.visibility), - // eslint-disable-next-line security/detect-object-injection - readonly: tablesAndAccessLevels[key].includes(AccessLevelEnum.readonly) && !readOnly, - add: addPermission, - delete: deletePermission, - edit: editPermission, - }, - }); - } - return tablesWithPermissions.filter((tableWithPermission: ITableAndViewPermissionData) => { - return !!tableWithPermission.accessLevel.visibility; - }); - } + const readOnly = !(addPermission || deletePermission || editPermission); + tablesWithPermissions.push({ + tableName: key, + isView: tables.find((table) => table.tableName === key).isView, + accessLevel: { + // eslint-disable-next-line security/detect-object-injection + visibility: tablesAndAccessLevels[key].includes(AccessLevelEnum.visibility), + // eslint-disable-next-line security/detect-object-injection + readonly: tablesAndAccessLevels[key].includes(AccessLevelEnum.readonly) && !readOnly, + add: addPermission, + delete: deletePermission, + edit: editPermission, + }, + }); + } + return tablesWithPermissions.filter((tableWithPermission: ITableAndViewPermissionData) => { + return !!tableWithPermission.accessLevel.visibility; + }); + } - private async saveTableInfoInDatabase( - connectionId: string, - _userId: string, - tables: Array, - masterPwd: string, - ): Promise { - try { - const foundConnection = await this._dbContext.connectionRepository.findOne({ where: { id: connectionId } }); - if (!foundConnection) { - return; - } - const decryptedConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( - connectionId, - masterPwd, - ); - const tableNames: Array = tables.map((table) => table.tableName); - const queue = new PQueue({ concurrency: 2 }); - const dao = getDataAccessObject(decryptedConnection); - const tablesStructures: Array<{ - tableName: string; - structure: Array; - }> = (await Promise.all( - tableNames.map(async (tableName) => { - return await queue.add(async () => { - const structure = await dao.getTableStructure(tableName, undefined); - return { - tableName: tableName, - structure: structure, - }; - }); - }), - )) as Array<{ - tableName: string; - structure: Array; - }>; - foundConnection.tables_info = (await Promise.all( - tablesStructures.map(async (tableStructure) => { - return await queue.add(async () => { - const newTableInfo = buildTableInfoEntity(tableStructure.tableName, foundConnection); - const savedTableInfo = await this._dbContext.tableInfoRepository.save(newTableInfo); - const newTableFieldsInfos = tableStructure.structure.map((el) => - buildTableFieldInfoEntity(el, savedTableInfo), - ); - newTableInfo.table_fields_info = await this._dbContext.tableFieldInfoRepository.save(newTableFieldsInfos); - await this._dbContext.tableInfoRepository.save(newTableInfo); - return newTableInfo; - }); - }), - )) as Array; - foundConnection.saved_table_info = ++foundConnection.saved_table_info; - await this._dbContext.connectionRepository.saveUpdatedConnection(foundConnection); - } catch (e) { - Sentry.captureException(e); - console.error(e); - } - } + private async saveTableInfoInDatabase( + connectionId: string, + _userId: string, + tables: Array, + masterPwd: string, + ): Promise { + try { + const foundConnection = await this._dbContext.connectionRepository.findOne({ where: { id: connectionId } }); + if (!foundConnection) { + return; + } + const decryptedConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( + connectionId, + masterPwd, + ); + const tableNames: Array = tables.map((table) => table.tableName); + const queue = new PQueue({ concurrency: 2 }); + const dao = getDataAccessObject(decryptedConnection); + const tablesStructures: Array<{ + tableName: string; + structure: Array; + }> = (await Promise.all( + tableNames.map(async (tableName) => { + return await queue.add(async () => { + const structure = await dao.getTableStructure(tableName, undefined); + return { + tableName: tableName, + structure: structure, + }; + }); + }), + )) as Array<{ + tableName: string; + structure: Array; + }>; + foundConnection.tables_info = (await Promise.all( + tablesStructures.map(async (tableStructure) => { + return await queue.add(async () => { + const newTableInfo = buildTableInfoEntity(tableStructure.tableName, foundConnection); + const savedTableInfo = await this._dbContext.tableInfoRepository.save(newTableInfo); + const newTableFieldsInfos = tableStructure.structure.map((el) => + buildTableFieldInfoEntity(el, savedTableInfo), + ); + newTableInfo.table_fields_info = await this._dbContext.tableFieldInfoRepository.save(newTableFieldsInfos); + await this._dbContext.tableInfoRepository.save(newTableInfo); + return newTableInfo; + }); + }), + )) as Array; + foundConnection.saved_table_info = ++foundConnection.saved_table_info; + await this._dbContext.connectionRepository.saveUpdatedConnection(foundConnection); + } catch (e) { + Sentry.captureException(e); + console.error(e); + } + } } diff --git a/backend/src/entities/table/use-cases/get-row-by-primary-key.use.case.ts b/backend/src/entities/table/use-cases/get-row-by-primary-key.use.case.ts index f8a4d26ce..925863931 100644 --- a/backend/src/entities/table/use-cases/get-row-by-primary-key.use.case.ts +++ b/backend/src/entities/table/use-cases/get-row-by-primary-key.use.case.ts @@ -1,31 +1,31 @@ /* eslint-disable prefer-const */ import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; +import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; +import { ForeignKeyDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key.ds.js'; +import { ForeignKeyWithAutocompleteColumnsDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key-with-autocomplete-columns.ds.js'; +import { ReferencedTableNamesAndColumnsDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/referenced-table-names-columns.ds.js'; +import { buildDAOsTableSettingsDs } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/table-settings.ds.builder.js'; +import { IDataAccessObject } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object.interface.js'; +import { IDataAccessObjectAgent } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object-agent.interface.js'; +import JSON5 from 'json5'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import { WidgetTypeEnum } from '../../../enums/index.js'; +import { ExceptionOperations } from '../../../exceptions/custom-exceptions/exception-operation.js'; +import { NonAvailableInFreePlanException } from '../../../exceptions/custom-exceptions/non-available-in-free-plan-exception.js'; +import { UnknownSQLException } from '../../../exceptions/custom-exceptions/unknown-sql-exception.js'; import { Messages } from '../../../exceptions/text/messages.js'; import { compareArrayElements, isConnectionTypeAgent } from '../../../helpers/index.js'; +import { buildActionEventDto } from '../../table-actions/table-action-rules-module/utils/build-found-action-event-dto.util.js'; import { GetRowByPrimaryKeyDs } from '../application/data-structures/get-row-by-primary-key.ds.js'; import { ForeignKeyDSInfo, ReferencedTableNamesAndColumnsDs, TableRowRODs } from '../table-datastructures.js'; import { convertBinaryDataInRowUtil } from '../utils/convert-binary-data-in-row.util.js'; import { convertHexDataInPrimaryKeyUtil } from '../utils/convert-hex-data-in-primary-key.util.js'; +import { findAvailableFields } from '../utils/find-available-fields.utils.js'; import { formFullTableStructure } from '../utils/form-full-table-structure.js'; import { removePasswordsFromRowsUtil } from '../utils/remove-password-from-row.util.js'; import { IGetRowByPrimaryKey } from './table-use-cases.interface.js'; -import { ForeignKeyWithAutocompleteColumnsDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key-with-autocomplete-columns.ds.js'; -import { ForeignKeyDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key.ds.js'; -import { UnknownSQLException } from '../../../exceptions/custom-exceptions/unknown-sql-exception.js'; -import { ExceptionOperations } from '../../../exceptions/custom-exceptions/exception-operation.js'; -import { ReferencedTableNamesAndColumnsDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/referenced-table-names-columns.ds.js'; -import JSON5 from 'json5'; -import { buildActionEventDto } from '../../table-actions/table-action-rules-module/utils/build-found-action-event-dto.util.js'; -import { NonAvailableInFreePlanException } from '../../../exceptions/custom-exceptions/non-available-in-free-plan-exception.js'; -import { findAvailableFields } from '../utils/find-available-fields.utils.js'; -import { IDataAccessObjectAgent } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object-agent.interface.js'; -import { IDataAccessObject } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object.interface.js'; -import { buildDAOsTableSettingsDs } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/table-settings.ds.builder.js'; @Injectable() export class GetRowByPrimaryKeyUseCase diff --git a/backend/src/entities/table/use-cases/get-table-rows.use.case.ts b/backend/src/entities/table/use-cases/get-table-rows.use.case.ts index 8c533ba5e..52fd1d514 100644 --- a/backend/src/entities/table/use-cases/get-table-rows.use.case.ts +++ b/backend/src/entities/table/use-cases/get-table-rows.use.case.ts @@ -1,8 +1,12 @@ import { BadRequestException, HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; -import { ForeignKeyWithAutocompleteColumnsDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key-with-autocomplete-columns.ds.js'; import { ForeignKeyDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key.ds.js'; +import { ForeignKeyWithAutocompleteColumnsDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key-with-autocomplete-columns.ds.js'; import { TableSettingsDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/table-settings.ds.js'; +import { buildDAOsTableSettingsDs } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/table-settings.ds.builder.js'; +import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; +import { IDataAccessObject } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object.interface.js'; +import { IDataAccessObjectAgent } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object-agent.interface.js'; import { FoundRowsDS } from '@rocketadmin/shared-code/src/data-access-layer/shared/data-structures/found-rows.ds.js'; import Sentry from '@sentry/minimal'; import JSON5 from 'json5'; @@ -27,22 +31,18 @@ import { buildActionEventDto } from '../../table-actions/table-action-rules-modu import { buildCreatedTableFilterRO } from '../../table-filters/utils/build-created-table-filters-response-object.util.js'; import { TableLogsService } from '../../table-logs/table-logs.service.js'; import { TableSettingsEntity } from '../../table-settings/common-table-settings/table-settings.entity.js'; +import { PersonalTableSettingsEntity } from '../../table-settings/personal-table-settings/personal-table-settings.entity.js'; import { FoundTableRowsDs } from '../application/data-structures/found-table-rows.ds.js'; import { GetTableRowsDs } from '../application/data-structures/get-table-rows.ds.js'; import { FilteringFieldsDs, ForeignKeyDSInfo } from '../table-datastructures.js'; import { findAutocompleteFieldsUtil } from '../utils/find-autocomplete-fields.util.js'; +import { findAvailableFields } from '../utils/find-available-fields.utils.js'; import { findFilteringFieldsUtil, parseFilteringFieldsFromBodyData } from '../utils/find-filtering-fields.util.js'; import { findOrderingFieldUtil } from '../utils/find-ordering-field.util.js'; import { formFullTableStructure } from '../utils/form-full-table-structure.js'; import { isHexString } from '../utils/is-hex-string.js'; import { processRowsUtil } from '../utils/process-found-rows-util.js'; import { IGetTableRows } from './table-use-cases.interface.js'; -import { findAvailableFields } from '../utils/find-available-fields.utils.js'; -import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; -import { IDataAccessObjectAgent } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object-agent.interface.js'; -import { IDataAccessObject } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object.interface.js'; -import { buildDAOsTableSettingsDs } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/table-settings.ds.builder.js'; -import { PersonalTableSettingsEntity } from '../../table-settings/personal-table-settings/personal-table-settings.entity.js'; @Injectable() export class GetTableRowsUseCase extends AbstractUseCase implements IGetTableRows { diff --git a/backend/src/entities/table/use-cases/get-table-structure.use.case.ts b/backend/src/entities/table/use-cases/get-table-structure.use.case.ts index 340571733..350ac6314 100644 --- a/backend/src/entities/table/use-cases/get-table-structure.use.case.ts +++ b/backend/src/entities/table/use-cases/get-table-structure.use.case.ts @@ -1,9 +1,9 @@ import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; -import { ForeignKeyWithAutocompleteColumnsDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key-with-autocomplete-columns.ds.js'; import { ForeignKeyDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key.ds.js'; -import { IDataAccessObjectAgent } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object-agent.interface.js'; +import { ForeignKeyWithAutocompleteColumnsDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key-with-autocomplete-columns.ds.js'; import { IDataAccessObject } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object.interface.js'; +import { IDataAccessObjectAgent } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object-agent.interface.js'; import JSON5 from 'json5'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; @@ -22,160 +22,160 @@ import { IGetTableStructure } from './table-use-cases.interface.js'; @Injectable() export class GetTableStructureUseCase - extends AbstractUseCase - implements IGetTableStructure + extends AbstractUseCase + implements IGetTableStructure { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: GetTableStructureDs): Promise { - const { connectionId, masterPwd, tableName, userId } = inputData; - const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( - connectionId, - masterPwd, - ); - if (!foundConnection) { - throw new HttpException( - { - message: Messages.CONNECTION_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } + protected async implementation(inputData: GetTableStructureDs): Promise { + const { connectionId, masterPwd, tableName, userId } = inputData; + const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( + connectionId, + masterPwd, + ); + if (!foundConnection) { + throw new HttpException( + { + message: Messages.CONNECTION_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } - if (foundConnection.is_frozen) { - throw new NonAvailableInFreePlanException(Messages.CONNECTION_IS_FROZEN); - } + if (foundConnection.is_frozen) { + throw new NonAvailableInFreePlanException(Messages.CONNECTION_IS_FROZEN); + } - try { - const dao = getDataAccessObject(foundConnection); - const foundTalesInConnection = await dao.getTablesFromDB(); - if (!foundTalesInConnection.find((el) => el.tableName === tableName)) { - throw new HttpException( - { - message: Messages.TABLE_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - let userEmail: string; - if (isConnectionTypeAgent(foundConnection.type)) { - userEmail = await this._dbContext.userRepository.getUserEmailOrReturnNull(userId); - } - // eslint-disable-next-line prefer-const - let [tableSettings, personalTableSettings, tablePrimaryColumns, tableForeignKeys, tableStructure, tableWidgets] = - await Promise.all([ - this._dbContext.tableSettingsRepository.findTableSettings(connectionId, tableName), - this._dbContext.personalTableSettingsRepository.findUserTableSettings(userId, connectionId, tableName), - dao.getTablePrimaryColumns(tableName, userEmail), - dao.getTableForeignKeys(tableName, userEmail), - dao.getTableStructure(tableName, userEmail), - this._dbContext.tableWidgetsRepository.findTableWidgets(connectionId, tableName), - ]); - const foreignKeysFromWidgets: Array = tableWidgets - .filter((widget) => widget.widget_type === WidgetTypeEnum.Foreign_key) - .map((widget) => { - if (widget.widget_params) { - try { - const widgetParams = JSON5.parse(widget.widget_params) as ForeignKeyDSInfo; - return widgetParams; - } catch (_e) { - return null; - } - } - }) - .filter((el) => el !== null); + try { + const dao = getDataAccessObject(foundConnection); + const foundTalesInConnection = await dao.getTablesFromDB(); + if (!foundTalesInConnection.find((el) => el.tableName === tableName)) { + throw new HttpException( + { + message: Messages.TABLE_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + let userEmail: string; + if (isConnectionTypeAgent(foundConnection.type)) { + userEmail = await this._dbContext.userRepository.getUserEmailOrReturnNull(userId); + } + // eslint-disable-next-line prefer-const + let [tableSettings, personalTableSettings, tablePrimaryColumns, tableForeignKeys, tableStructure, tableWidgets] = + await Promise.all([ + this._dbContext.tableSettingsRepository.findTableSettings(connectionId, tableName), + this._dbContext.personalTableSettingsRepository.findUserTableSettings(userId, connectionId, tableName), + dao.getTablePrimaryColumns(tableName, userEmail), + dao.getTableForeignKeys(tableName, userEmail), + dao.getTableStructure(tableName, userEmail), + this._dbContext.tableWidgetsRepository.findTableWidgets(connectionId, tableName), + ]); + const foreignKeysFromWidgets: Array = tableWidgets + .filter((widget) => widget.widget_type === WidgetTypeEnum.Foreign_key) + .map((widget) => { + if (widget.widget_params) { + try { + const widgetParams = JSON5.parse(widget.widget_params) as ForeignKeyDSInfo; + return widgetParams; + } catch (_e) { + return null; + } + } + }) + .filter((el) => el !== null); - tableForeignKeys = tableForeignKeys.concat(foreignKeysFromWidgets); - let transformedTableForeignKeys: Array = []; - const canUserReadForeignTables: Array<{ - tableName: string; - canRead: boolean; - }> = await Promise.all( - tableForeignKeys.map(async (foreignKey) => { - const cenTableRead = await this._dbContext.userAccessRepository.improvedCheckTableRead( - userId, - connectionId, - foreignKey.referenced_table_name, - masterPwd, - ); - return { - tableName: foreignKey.referenced_table_name, - canRead: cenTableRead, - }; - }), - ); - tableForeignKeys = tableForeignKeys.filter((foreignKey) => { - return canUserReadForeignTables.find((el) => { - return el.tableName === foreignKey.referenced_table_name && el.canRead; - }); - }); + tableForeignKeys = tableForeignKeys.concat(foreignKeysFromWidgets); + let transformedTableForeignKeys: Array = []; + const canUserReadForeignTables: Array<{ + tableName: string; + canRead: boolean; + }> = await Promise.all( + tableForeignKeys.map(async (foreignKey) => { + const cenTableRead = await this._dbContext.userAccessRepository.improvedCheckTableRead( + userId, + connectionId, + foreignKey.referenced_table_name, + masterPwd, + ); + return { + tableName: foreignKey.referenced_table_name, + canRead: cenTableRead, + }; + }), + ); + tableForeignKeys = tableForeignKeys.filter((foreignKey) => { + return canUserReadForeignTables.find((el) => { + return el.tableName === foreignKey.referenced_table_name && el.canRead; + }); + }); - if (tableForeignKeys && tableForeignKeys.length > 0) { - transformedTableForeignKeys = await Promise.all( - tableForeignKeys.map((el) => { - try { - return this.attachForeignColumnNames(el, userId, connectionId, dao); - } catch (_e) { - return el as ForeignKeyWithAutocompleteColumnsDS; - } - }), - ); - } - const readonly_fields = tableSettings?.readonly_fields?.length > 0 ? tableSettings.readonly_fields : []; - const formedTableStructure = formFullTableStructure(tableStructure, tableSettings); - return { - structure: formedTableStructure, - primaryColumns: tablePrimaryColumns, - foreignKeys: transformedTableForeignKeys, - readonly_fields: readonly_fields, - table_widgets: tableWidgets?.length > 0 ? tableWidgets.map((widget) => buildFoundTableWidgetDs(widget)) : [], - list_fields: personalTableSettings?.list_fields ? personalTableSettings.list_fields : [], - display_name: tableSettings?.display_name ? tableSettings.display_name : null, - excluded_fields: tableSettings?.excluded_fields ? tableSettings.excluded_fields : [], - }; - } catch (e) { - if (e instanceof HttpException) { - throw e; - } - throw new UnknownSQLException(e.message, ExceptionOperations.FAILED_TO_GET_TABLE_STRUCTURE); - } - } + if (tableForeignKeys && tableForeignKeys.length > 0) { + transformedTableForeignKeys = await Promise.all( + tableForeignKeys.map((el) => { + try { + return this.attachForeignColumnNames(el, userId, connectionId, dao); + } catch (_e) { + return el as ForeignKeyWithAutocompleteColumnsDS; + } + }), + ); + } + const readonly_fields = tableSettings?.readonly_fields?.length > 0 ? tableSettings.readonly_fields : []; + const formedTableStructure = formFullTableStructure(tableStructure, tableSettings); + return { + structure: formedTableStructure, + primaryColumns: tablePrimaryColumns, + foreignKeys: transformedTableForeignKeys, + readonly_fields: readonly_fields, + table_widgets: tableWidgets?.length > 0 ? tableWidgets.map((widget) => buildFoundTableWidgetDs(widget)) : [], + list_fields: personalTableSettings?.list_fields ? personalTableSettings.list_fields : [], + display_name: tableSettings?.display_name ? tableSettings.display_name : null, + excluded_fields: tableSettings?.excluded_fields ? tableSettings.excluded_fields : [], + }; + } catch (e) { + if (e instanceof HttpException) { + throw e; + } + throw new UnknownSQLException(e.message, ExceptionOperations.FAILED_TO_GET_TABLE_STRUCTURE); + } + } - private async attachForeignColumnNames( - foreignKey: ForeignKeyDS, - userId: string, - connectionId: string, - dao: IDataAccessObject | IDataAccessObjectAgent, - ): Promise { - try { - const [foreignTableSettings, foreignTableStructure] = await Promise.all([ - this._dbContext.tableSettingsRepository.findTableSettings(connectionId, foreignKey.referenced_table_name), - dao.getTableStructure(foreignKey.referenced_table_name, userId), - ]); + private async attachForeignColumnNames( + foreignKey: ForeignKeyDS, + userId: string, + connectionId: string, + dao: IDataAccessObject | IDataAccessObjectAgent, + ): Promise { + try { + const [foreignTableSettings, foreignTableStructure] = await Promise.all([ + this._dbContext.tableSettingsRepository.findTableSettings(connectionId, foreignKey.referenced_table_name), + dao.getTableStructure(foreignKey.referenced_table_name, userId), + ]); - let columnNames = foreignTableStructure.map((el) => { - return el.column_name; - }); - if (foreignTableSettings && foreignTableSettings.autocomplete_columns.length > 0) { - columnNames = columnNames.filter((el) => { - const index = foreignTableSettings.autocomplete_columns.indexOf(el); - return index >= 0; - }); - } - return { - ...foreignKey, - autocomplete_columns: columnNames, - }; - } catch (_e) { - return { - ...foreignKey, - autocomplete_columns: [], - }; - } - } + let columnNames = foreignTableStructure.map((el) => { + return el.column_name; + }); + if (foreignTableSettings && foreignTableSettings.autocomplete_columns.length > 0) { + columnNames = columnNames.filter((el) => { + const index = foreignTableSettings.autocomplete_columns.indexOf(el); + return index >= 0; + }); + } + return { + ...foreignKey, + autocomplete_columns: columnNames, + }; + } catch (_e) { + return { + ...foreignKey, + autocomplete_columns: [], + }; + } + } } diff --git a/backend/src/entities/table/use-cases/import-csv-in-table-user.case.ts b/backend/src/entities/table/use-cases/import-csv-in-table-user.case.ts index 538f0c770..4a69da468 100644 --- a/backend/src/entities/table/use-cases/import-csv-in-table-user.case.ts +++ b/backend/src/entities/table/use-cases/import-csv-in-table-user.case.ts @@ -1,80 +1,80 @@ import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; +import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { IImportCSVFinTable } from './table-use-cases.interface.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import { ImportCSVInTableDs } from '../application/data-structures/import-scv-in-table.ds.js'; +import { NonAvailableInFreePlanException } from '../../../exceptions/custom-exceptions/non-available-in-free-plan-exception.js'; import { Messages } from '../../../exceptions/text/messages.js'; -import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; import { isConnectionTypeAgent } from '../../../helpers/is-connection-entity-agent.js'; -import { NonAvailableInFreePlanException } from '../../../exceptions/custom-exceptions/non-available-in-free-plan-exception.js'; +import { ImportCSVInTableDs } from '../application/data-structures/import-scv-in-table.ds.js'; +import { IImportCSVFinTable } from './table-use-cases.interface.js'; @Injectable() export class ImportCSVInTableUseCase - extends AbstractUseCase - implements IImportCSVFinTable + extends AbstractUseCase + implements IImportCSVFinTable { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: ImportCSVInTableDs): Promise { - const { file, tableName, connectionId, materPwd, userId } = inputData; - const connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, materPwd); - if (!connection) { - throw new HttpException( - { - message: Messages.CONNECTION_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } + protected async implementation(inputData: ImportCSVInTableDs): Promise { + const { file, tableName, connectionId, materPwd, userId } = inputData; + const connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, materPwd); + if (!connection) { + throw new HttpException( + { + message: Messages.CONNECTION_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } - if (connection.is_frozen) { - throw new NonAvailableInFreePlanException(Messages.CONNECTION_IS_FROZEN); - } + if (connection.is_frozen) { + throw new NonAvailableInFreePlanException(Messages.CONNECTION_IS_FROZEN); + } - if (connection.isTestConnection) { - throw new HttpException( - { - message: Messages.CSV_IMPORT_DISABLED_FOR_TEST_CONNECTIONS, - }, - HttpStatus.BAD_REQUEST, - ); - } + if (connection.isTestConnection) { + throw new HttpException( + { + message: Messages.CSV_IMPORT_DISABLED_FOR_TEST_CONNECTIONS, + }, + HttpStatus.BAD_REQUEST, + ); + } - const foundTableSettings = await this._dbContext.tableSettingsRepository.findTableSettings(connectionId, tableName); + const foundTableSettings = await this._dbContext.tableSettingsRepository.findTableSettings(connectionId, tableName); - if (foundTableSettings?.allow_csv_import === false) { - throw new HttpException( - { - message: Messages.CSV_IMPORT_DISABLED, - }, - HttpStatus.BAD_REQUEST, - ); - } + if (foundTableSettings?.allow_csv_import === false) { + throw new HttpException( + { + message: Messages.CSV_IMPORT_DISABLED, + }, + HttpStatus.BAD_REQUEST, + ); + } - try { - const dao = getDataAccessObject(connection); - let userEmail: string; - if (isConnectionTypeAgent(connection.type)) { - userEmail = await this._dbContext.userRepository.getUserEmailOrReturnNull(userId); - } - await dao.importCSVInTable(file, tableName, userEmail); - return true; - } catch (error) { - if (error instanceof HttpException) { - throw error; - } - throw new HttpException( - { - message: `${Messages.CSV_IMPORT_FAILED}. ${error.message}`, - }, - HttpStatus.INTERNAL_SERVER_ERROR, - ); - } - } + try { + const dao = getDataAccessObject(connection); + let userEmail: string; + if (isConnectionTypeAgent(connection.type)) { + userEmail = await this._dbContext.userRepository.getUserEmailOrReturnNull(userId); + } + await dao.importCSVInTable(file, tableName, userEmail); + return true; + } catch (error) { + if (error instanceof HttpException) { + throw error; + } + throw new HttpException( + { + message: `${Messages.CSV_IMPORT_FAILED}. ${error.message}`, + }, + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } } diff --git a/backend/src/entities/table/use-cases/table-use-cases.interface.ts b/backend/src/entities/table/use-cases/table-use-cases.interface.ts index 1937ad4a0..130336b58 100644 --- a/backend/src/entities/table/use-cases/table-use-cases.interface.ts +++ b/backend/src/entities/table/use-cases/table-use-cases.interface.ts @@ -1,67 +1,67 @@ import { StreamableFile } from '@nestjs/common'; import { InTransactionEnum } from '../../../enums/index.js'; +import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; import { AddRowInTableDs } from '../application/data-structures/add-row-in-table.ds.js'; import { - DeleteRowFromTableDs, - DeleteRowsFromTableDs, + DeleteRowFromTableDs, + DeleteRowsFromTableDs, } from '../application/data-structures/delete-row-from-table.ds.js'; import { DeletedRowFromTableDs } from '../application/data-structures/deleted-row-from-table.ds.js'; import { FindTablesDs } from '../application/data-structures/find-tables.ds.js'; -import { FoundTableRowsDs } from '../application/data-structures/found-table-rows.ds.js'; import { FoundTableDs, FoundTablesWithCategoriesDS } from '../application/data-structures/found-table.ds.js'; +import { FoundTableRowsDs } from '../application/data-structures/found-table-rows.ds.js'; import { GetRowByPrimaryKeyDs } from '../application/data-structures/get-row-by-primary-key.ds.js'; import { GetTableRowsDs } from '../application/data-structures/get-table-rows.ds.js'; import { GetTableStructureDs } from '../application/data-structures/get-table-structure-ds.js'; +import { ImportCSVInTableDs } from '../application/data-structures/import-scv-in-table.ds.js'; import { UpdateRowInTableDs } from '../application/data-structures/update-row-in-table.ds.js'; -import { TableStructureDs, TableRowRODs } from '../table-datastructures.js'; import { UpdateRowsInTableDs } from '../application/data-structures/update-rows-in-table.ds.js'; -import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; -import { ImportCSVInTableDs } from '../application/data-structures/import-scv-in-table.ds.js'; +import { TableRowRODs, TableStructureDs } from '../table-datastructures.js'; export interface IFindTablesInConnection { - execute(inputData: FindTablesDs, inTransaction: InTransactionEnum): Promise>; + execute(inputData: FindTablesDs, inTransaction: InTransactionEnum): Promise>; } export interface IFindTablesInConnectionV2 { - execute(inputData: FindTablesDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: FindTablesDs, inTransaction: InTransactionEnum): Promise; } export interface IGetTableRows { - execute(inputData: GetTableRowsDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: GetTableRowsDs, inTransaction: InTransactionEnum): Promise; } export interface IGetTableStructure { - execute(inputData: GetTableStructureDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: GetTableStructureDs, inTransaction: InTransactionEnum): Promise; } export interface IAddRowInTable { - execute(inputData: AddRowInTableDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: AddRowInTableDs, inTransaction: InTransactionEnum): Promise; } export interface IUpdateRowInTable { - execute(inputData: UpdateRowInTableDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: UpdateRowInTableDs, inTransaction: InTransactionEnum): Promise; } export interface IBulkUpdateRowsInTable { - execute(inputData: UpdateRowsInTableDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: UpdateRowsInTableDs, inTransaction: InTransactionEnum): Promise; } export interface IDeleteRowFromTable { - execute(inputData: DeleteRowFromTableDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: DeleteRowFromTableDs, inTransaction: InTransactionEnum): Promise; } export interface IDeleteRowsFromTable { - execute(inputData: DeleteRowsFromTableDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: DeleteRowsFromTableDs, inTransaction: InTransactionEnum): Promise; } export interface IGetRowByPrimaryKey { - execute(inputData: GetRowByPrimaryKeyDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: GetRowByPrimaryKeyDs, inTransaction: InTransactionEnum): Promise; } export interface IExportCSVFromTable { - execute(inputData: GetTableRowsDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: GetTableRowsDs, inTransaction: InTransactionEnum): Promise; } export interface IImportCSVFinTable { - execute(inputData: ImportCSVInTableDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: ImportCSVInTableDs, inTransaction: InTransactionEnum): Promise; } diff --git a/backend/src/entities/table/use-cases/update-row-in-table.use.case.ts b/backend/src/entities/table/use-cases/update-row-in-table.use.case.ts index 1a578101b..dc80aeaf2 100644 --- a/backend/src/entities/table/use-cases/update-row-in-table.use.case.ts +++ b/backend/src/entities/table/use-cases/update-row-in-table.use.case.ts @@ -1,11 +1,12 @@ /* eslint-disable prefer-const */ import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; -import { ForeignKeyWithAutocompleteColumnsDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key-with-autocomplete-columns.ds.js'; import { ForeignKeyDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key.ds.js'; +import { ForeignKeyWithAutocompleteColumnsDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/foreign-key-with-autocomplete-columns.ds.js'; import { ReferencedTableNamesAndColumnsDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/referenced-table-names-columns.ds.js'; -import { IDataAccessObjectAgent } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object-agent.interface.js'; +import { buildDAOsTableSettingsDs } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/table-settings.ds.builder.js'; import { IDataAccessObject } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object.interface.js'; +import { IDataAccessObjectAgent } from '@rocketadmin/shared-code/dist/src/shared/interfaces/data-access-object-agent.interface.js'; import JSON5 from 'json5'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; @@ -39,7 +40,6 @@ import { hashPasswordsInRowUtil } from '../utils/hash-passwords-in-row.util.js'; import { processUuidsInRowUtil } from '../utils/process-uuids-in-row-util.js'; import { removePasswordsFromRowsUtil } from '../utils/remove-password-from-row.util.js'; import { IUpdateRowInTable } from './table-use-cases.interface.js'; -import { buildDAOsTableSettingsDs } from '@rocketadmin/shared-code/dist/src/helpers/data-structures-builders/table-settings.ds.builder.js'; @Injectable() export class UpdateRowInTableUseCase diff --git a/backend/src/entities/table/utils/convert-binary-data-in-row.util.ts b/backend/src/entities/table/utils/convert-binary-data-in-row.util.ts index 31ed990d1..40da77b2c 100644 --- a/backend/src/entities/table/utils/convert-binary-data-in-row.util.ts +++ b/backend/src/entities/table/utils/convert-binary-data-in-row.util.ts @@ -2,27 +2,27 @@ import { TableStructureDS } from '@rocketadmin/shared-code/dist/src/data-access- import { binaryToHex, isBinary } from '../../../helpers/index.js'; export function convertBinaryDataInRowUtil( - row: Record, - structure: Array, + row: Record, + structure: Array, ): Record { - const binaryColumns = structure - .map((el) => { - return { - column_name: el.column_name, - data_type: el.data_type, - }; - }) - .filter((el) => { - return isBinary(el.data_type); - }); - if (binaryColumns.length <= 0) { - return row; - } + const binaryColumns = structure + .map((el) => { + return { + column_name: el.column_name, + data_type: el.data_type, + }; + }) + .filter((el) => { + return isBinary(el.data_type); + }); + if (binaryColumns.length <= 0) { + return row; + } - for (const column of binaryColumns) { - if (row[column.column_name]) { - row[column.column_name] = binaryToHex(row[column.column_name] as string); - } - } - return row; + for (const column of binaryColumns) { + if (row[column.column_name]) { + row[column.column_name] = binaryToHex(row[column.column_name] as string); + } + } + return row; } diff --git a/backend/src/entities/table/utils/convert-hex-data-in-primary-key.util.ts b/backend/src/entities/table/utils/convert-hex-data-in-primary-key.util.ts index bdbdc90b4..08dcb57d5 100644 --- a/backend/src/entities/table/utils/convert-hex-data-in-primary-key.util.ts +++ b/backend/src/entities/table/utils/convert-hex-data-in-primary-key.util.ts @@ -1,19 +1,19 @@ -import { isBinary } from '../../../helpers/index.js'; -import { hexToBinary } from '../../../helpers/binary-to-hex.js'; import { TableStructureDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/table-structure.ds.js'; +import { hexToBinary } from '../../../helpers/binary-to-hex.js'; +import { isBinary } from '../../../helpers/index.js'; export function convertHexDataInPrimaryKeyUtil( - primaryKey: Record, - structure: Array, + primaryKey: Record, + structure: Array, ): Record { - const binaryColumns = structure.filter((el) => isBinary(el.data_type)); + const binaryColumns = structure.filter((el) => isBinary(el.data_type)); - for (const column of binaryColumns) { - const columnValue = primaryKey[column.column_name]; - if (columnValue) { - primaryKey[column.column_name] = hexToBinary(columnValue as string); - } - } + for (const column of binaryColumns) { + const columnValue = primaryKey[column.column_name]; + if (columnValue) { + primaryKey[column.column_name] = hexToBinary(columnValue as string); + } + } - return primaryKey; + return primaryKey; } diff --git a/backend/src/entities/table/utils/convert-hex-data-in-row.util.ts b/backend/src/entities/table/utils/convert-hex-data-in-row.util.ts index 3176ff971..c9cd61b6f 100644 --- a/backend/src/entities/table/utils/convert-hex-data-in-row.util.ts +++ b/backend/src/entities/table/utils/convert-hex-data-in-row.util.ts @@ -1,19 +1,19 @@ -import { isBinary } from '../../../helpers/index.js'; -import { hexToBinary } from '../../../helpers/binary-to-hex.js'; import { TableStructureDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/table-structure.ds.js'; +import { hexToBinary } from '../../../helpers/binary-to-hex.js'; +import { isBinary } from '../../../helpers/index.js'; export function convertHexDataInRowUtil( - row: Record, - structure: Array, + row: Record, + structure: Array, ): Record { - const binaryColumns = structure.filter((el) => isBinary(el.data_type)); + const binaryColumns = structure.filter((el) => isBinary(el.data_type)); - for (const column of binaryColumns) { - const columnValue = row[column.column_name]; - if (columnValue) { - row[column.column_name] = hexToBinary(columnValue as string); - } - } + for (const column of binaryColumns) { + const columnValue = row[column.column_name]; + if (columnValue) { + row[column.column_name] = hexToBinary(columnValue as string); + } + } - return row; + return row; } diff --git a/backend/src/entities/table/utils/find-autocomplete-fields.util.ts b/backend/src/entities/table/utils/find-autocomplete-fields.util.ts index 61a808412..ca1cfc0c4 100644 --- a/backend/src/entities/table/utils/find-autocomplete-fields.util.ts +++ b/backend/src/entities/table/utils/find-autocomplete-fields.util.ts @@ -1,46 +1,46 @@ -import { TableSettingsEntity } from '../../table-settings/common-table-settings/table-settings.entity.js'; -import { AutocompleteFieldsDs } from '../application/data-structures/found-table-rows.ds.js'; import { HttpException, HttpStatus } from '@nestjs/common'; -import { Messages } from '../../../exceptions/text/messages.js'; import { TableStructureDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/table-structure.ds.js'; +import { Messages } from '../../../exceptions/text/messages.js'; +import { TableSettingsEntity } from '../../table-settings/common-table-settings/table-settings.entity.js'; +import { AutocompleteFieldsDs } from '../application/data-structures/found-table-rows.ds.js'; export function findAutocompleteFieldsUtil( - query: Record, - tableStructure: Array, - tableSettings: TableSettingsEntity, - referencedColumn: string, + query: Record, + tableStructure: Array, + tableSettings: TableSettingsEntity, + referencedColumn: string, ): AutocompleteFieldsDs { - const rowNames = new Set(tableStructure.map((el) => el.column_name)); + const rowNames = new Set(tableStructure.map((el) => el.column_name)); - if (tableSettings?.excluded_fields?.includes(referencedColumn) || !rowNames.has(referencedColumn)) { - throw new HttpException( - { - message: Messages.EXCLUDED_OR_NOT_EXISTS(referencedColumn), - }, - HttpStatus.BAD_REQUEST, - ); - } + if (tableSettings?.excluded_fields?.includes(referencedColumn) || !rowNames.has(referencedColumn)) { + throw new HttpException( + { + message: Messages.EXCLUDED_OR_NOT_EXISTS(referencedColumn), + }, + HttpStatus.BAD_REQUEST, + ); + } - let autocompleteFields = [referencedColumn]; + let autocompleteFields = [referencedColumn]; - if (tableSettings?.autocomplete_columns) { - autocompleteFields.push(...tableSettings.autocomplete_columns.filter((column) => rowNames.has(column))); - } else if (tableSettings?.excluded_fields) { - autocompleteFields.push( - ...tableSettings.excluded_fields.filter( - (column) => rowNames.has(column) && !tableSettings.excluded_fields.includes(column), - ), - ); - } else { - autocompleteFields = [...rowNames]; - } + if (tableSettings?.autocomplete_columns) { + autocompleteFields.push(...tableSettings.autocomplete_columns.filter((column) => rowNames.has(column))); + } else if (tableSettings?.excluded_fields) { + autocompleteFields.push( + ...tableSettings.excluded_fields.filter( + (column) => rowNames.has(column) && !tableSettings.excluded_fields.includes(column), + ), + ); + } else { + autocompleteFields = [...rowNames]; + } - if (tableSettings?.identity_column && !autocompleteFields.includes(tableSettings.identity_column)) { - autocompleteFields.unshift(tableSettings.identity_column); - } + if (tableSettings?.identity_column && !autocompleteFields.includes(tableSettings.identity_column)) { + autocompleteFields.unshift(tableSettings.identity_column); + } - return { - fields: autocompleteFields, - value: query.autocomplete === '' ? '*' : (query.autocomplete as string), - }; + return { + fields: autocompleteFields, + value: query.autocomplete === '' ? '*' : (query.autocomplete as string), + }; } diff --git a/backend/src/entities/table/utils/find-available-fields.utils.ts b/backend/src/entities/table/utils/find-available-fields.utils.ts index 525e7cba6..cfca24155 100644 --- a/backend/src/entities/table/utils/find-available-fields.utils.ts +++ b/backend/src/entities/table/utils/find-available-fields.utils.ts @@ -3,41 +3,41 @@ import { TableStructureDS } from '@rocketadmin/shared-code/dist/src/data-access- import { isObjectEmpty } from '../../../helpers/is-object-empty.js'; export function findAvailableFields(settings: TableSettingsDS, tableStructure: Array): Array { - let availableFields: Array = []; - const fieldsFromStructure = tableStructure.map((el) => { - return el.column_name; - }); + let availableFields: Array = []; + const fieldsFromStructure = tableStructure.map((el) => { + return el.column_name; + }); - if (isObjectEmpty(settings)) { - availableFields = tableStructure.map((el) => { - return el.column_name; - }); - return availableFields; - } - const excludedFields = settings.excluded_fields; + if (isObjectEmpty(settings)) { + availableFields = tableStructure.map((el) => { + return el.column_name; + }); + return availableFields; + } + const excludedFields = settings.excluded_fields; - if (settings.list_fields && settings.list_fields.length > 0) { - const validListFields = settings.list_fields.filter((fieldName) => { - return fieldsFromStructure.includes(fieldName); - }); + if (settings.list_fields && settings.list_fields.length > 0) { + const validListFields = settings.list_fields.filter((fieldName) => { + return fieldsFromStructure.includes(fieldName); + }); - const additionalFields = fieldsFromStructure.filter((fieldName) => { - return !settings.list_fields.includes(fieldName); - }); + const additionalFields = fieldsFromStructure.filter((fieldName) => { + return !settings.list_fields.includes(fieldName); + }); - availableFields = [...validListFields, ...additionalFields]; - } else { - availableFields = tableStructure.map((el) => { - return el.column_name; - }); - } - if (excludedFields && excludedFields.length > 0) { - for (const field of excludedFields) { - const delIndex = availableFields.indexOf(field); - if (delIndex >= 0) { - availableFields.splice(availableFields.indexOf(field), 1); - } - } - } - return availableFields; + availableFields = [...validListFields, ...additionalFields]; + } else { + availableFields = tableStructure.map((el) => { + return el.column_name; + }); + } + if (excludedFields && excludedFields.length > 0) { + for (const field of excludedFields) { + const delIndex = availableFields.indexOf(field); + if (delIndex >= 0) { + availableFields.splice(availableFields.indexOf(field), 1); + } + } + } + return availableFields; } diff --git a/backend/src/entities/table/utils/find-filtering-fields.util.ts b/backend/src/entities/table/utils/find-filtering-fields.util.ts index 428934651..03dcdfc6e 100644 --- a/backend/src/entities/table/utils/find-filtering-fields.util.ts +++ b/backend/src/entities/table/utils/find-filtering-fields.util.ts @@ -1,115 +1,116 @@ /* eslint-disable security/detect-object-injection */ -import { FilteringFieldsDs } from '../application/data-structures/found-table-rows.ds.js'; -import { FilterCriteriaEnum } from '../../../enums/index.js'; + import { TableStructureDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/table-structure.ds.js'; -import { validateStringWithEnum } from '../../../helpers/validators/validate-string-with-enum.js'; +import { FilterCriteriaEnum } from '../../../enums/index.js'; import { isObjectPropertyExists } from '../../../helpers/validators/is-object-property-exists-validator.js'; +import { validateStringWithEnum } from '../../../helpers/validators/validate-string-with-enum.js'; +import { FilteringFieldsDs } from '../application/data-structures/found-table-rows.ds.js'; export function findFilteringFieldsUtil( - filters: Record, - tableStructure: Array, + filters: Record, + tableStructure: Array, ): Array { - const rowNames = tableStructure.map((el) => { - return el.column_name; - }); - const filteringItems = []; - for (const fieldname of rowNames) { - if (isObjectPropertyExists(filters, `f_${fieldname}__eq`)) { - filteringItems.push({ - field: fieldname, - criteria: FilterCriteriaEnum.eq, - value: filters[`f_${fieldname}__eq`], - }); - } + const rowNames = tableStructure.map((el) => { + return el.column_name; + }); + const filteringItems = []; + for (const fieldname of rowNames) { + if (isObjectPropertyExists(filters, `f_${fieldname}__eq`)) { + filteringItems.push({ + field: fieldname, + criteria: FilterCriteriaEnum.eq, + value: filters[`f_${fieldname}__eq`], + }); + } - if (isObjectPropertyExists(filters, `f_${fieldname}__startswith`)) { - filteringItems.push({ - field: fieldname, - criteria: FilterCriteriaEnum.startswith, - value: filters[`f_${fieldname}__startswith`], - }); - } - if (isObjectPropertyExists(filters, `f_${fieldname}__endswith`)) { - filteringItems.push({ - field: fieldname, - criteria: FilterCriteriaEnum.endswith, - value: filters[`f_${fieldname}__endswith`], - }); - } - if (isObjectPropertyExists(filters, `f_${fieldname}__gt`)) { - filteringItems.push({ - field: fieldname, - criteria: FilterCriteriaEnum.gt, - value: filters[`f_${fieldname}__gt`], - }); - } - if (isObjectPropertyExists(filters, `f_${fieldname}__lt`)) { - filteringItems.push({ - field: fieldname, - criteria: FilterCriteriaEnum.lt, - value: filters[`f_${fieldname}__lt`], - }); - } - if (isObjectPropertyExists(filters, `f_${fieldname}__lte`)) { - filteringItems.push({ - field: fieldname, - criteria: FilterCriteriaEnum.lte, - value: filters[`f_${fieldname}__lte`], - }); - } - if (isObjectPropertyExists(filters, `f_${fieldname}__gte`)) { - filteringItems.push({ - field: fieldname, - criteria: FilterCriteriaEnum.gte, - value: filters[`f_${fieldname}__gte`], - }); - } - if (isObjectPropertyExists(filters, `f_${fieldname}__contains`)) { - filteringItems.push({ - field: fieldname, - criteria: FilterCriteriaEnum.contains, - value: filters[`f_${fieldname}__contains`], - }); - } - if (isObjectPropertyExists(filters, `f_${fieldname}__icontains`)) { - filteringItems.push({ - field: fieldname, - criteria: FilterCriteriaEnum.icontains, - value: filters[`f_${fieldname}__icontains`], - }); - } + if (isObjectPropertyExists(filters, `f_${fieldname}__startswith`)) { + filteringItems.push({ + field: fieldname, + criteria: FilterCriteriaEnum.startswith, + value: filters[`f_${fieldname}__startswith`], + }); + } + if (isObjectPropertyExists(filters, `f_${fieldname}__endswith`)) { + filteringItems.push({ + field: fieldname, + criteria: FilterCriteriaEnum.endswith, + value: filters[`f_${fieldname}__endswith`], + }); + } + if (isObjectPropertyExists(filters, `f_${fieldname}__gt`)) { + filteringItems.push({ + field: fieldname, + criteria: FilterCriteriaEnum.gt, + value: filters[`f_${fieldname}__gt`], + }); + } + if (isObjectPropertyExists(filters, `f_${fieldname}__lt`)) { + filteringItems.push({ + field: fieldname, + criteria: FilterCriteriaEnum.lt, + value: filters[`f_${fieldname}__lt`], + }); + } + if (isObjectPropertyExists(filters, `f_${fieldname}__lte`)) { + filteringItems.push({ + field: fieldname, + criteria: FilterCriteriaEnum.lte, + value: filters[`f_${fieldname}__lte`], + }); + } + if (isObjectPropertyExists(filters, `f_${fieldname}__gte`)) { + filteringItems.push({ + field: fieldname, + criteria: FilterCriteriaEnum.gte, + value: filters[`f_${fieldname}__gte`], + }); + } + if (isObjectPropertyExists(filters, `f_${fieldname}__contains`)) { + filteringItems.push({ + field: fieldname, + criteria: FilterCriteriaEnum.contains, + value: filters[`f_${fieldname}__contains`], + }); + } + if (isObjectPropertyExists(filters, `f_${fieldname}__icontains`)) { + filteringItems.push({ + field: fieldname, + criteria: FilterCriteriaEnum.icontains, + value: filters[`f_${fieldname}__icontains`], + }); + } - if (isObjectPropertyExists(filters, `f_${fieldname}__empty`)) { - filteringItems.push({ - field: fieldname, - criteria: FilterCriteriaEnum.empty, - value: filters[`f_${fieldname}__empty`], - }); - } - } - return filteringItems; + if (isObjectPropertyExists(filters, `f_${fieldname}__empty`)) { + filteringItems.push({ + field: fieldname, + criteria: FilterCriteriaEnum.empty, + value: filters[`f_${fieldname}__empty`], + }); + } + } + return filteringItems; } export function parseFilteringFieldsFromBodyData( - filtersDataFromBody: Record, - tableStructure: Array, + filtersDataFromBody: Record, + tableStructure: Array, ): Array { - const filteringItems: Array = []; - const rowNames = tableStructure.map((el) => el.column_name); - rowNames.forEach((rowName) => { - if (isObjectPropertyExists(filtersDataFromBody, rowName)) { - for (const key in filtersDataFromBody[rowName]) { - if (!validateStringWithEnum(key, FilterCriteriaEnum)) { - throw new Error(`Invalid filter criteria: "${key}".`); - } - const isValueNull = filtersDataFromBody[rowName][key] === null && key === FilterCriteriaEnum.eq; - filteringItems.push({ - field: rowName, - criteria: isValueNull ? FilterCriteriaEnum.empty : (key as FilterCriteriaEnum), - value: filtersDataFromBody[rowName][key], - }); - } - } - }); - return filteringItems; + const filteringItems: Array = []; + const rowNames = tableStructure.map((el) => el.column_name); + rowNames.forEach((rowName) => { + if (isObjectPropertyExists(filtersDataFromBody, rowName)) { + for (const key in filtersDataFromBody[rowName]) { + if (!validateStringWithEnum(key, FilterCriteriaEnum)) { + throw new Error(`Invalid filter criteria: "${key}".`); + } + const isValueNull = filtersDataFromBody[rowName][key] === null && key === FilterCriteriaEnum.eq; + filteringItems.push({ + field: rowName, + criteria: isValueNull ? FilterCriteriaEnum.empty : (key as FilterCriteriaEnum), + value: filtersDataFromBody[rowName][key], + }); + } + } + }); + return filteringItems; } diff --git a/backend/src/entities/table/utils/find-objects-with-properties.ts b/backend/src/entities/table/utils/find-objects-with-properties.ts index 286396304..59000a102 100644 --- a/backend/src/entities/table/utils/find-objects-with-properties.ts +++ b/backend/src/entities/table/utils/find-objects-with-properties.ts @@ -1,6 +1,6 @@ export function findObjectsWithProperties(objectsArray: T[], properties: Pick): T[] { - return objectsArray.filter((obj) => { - // eslint-disable-next-line security/detect-object-injection - return Object.entries(properties).every(([key, value]) => obj[key] === value); - }); + return objectsArray.filter((obj) => { + // eslint-disable-next-line security/detect-object-injection + return Object.entries(properties).every(([key, value]) => obj[key] === value); + }); } diff --git a/backend/src/entities/table/utils/find-ordering-field.util.ts b/backend/src/entities/table/utils/find-ordering-field.util.ts index 89ed1ee87..ef1a2c735 100644 --- a/backend/src/entities/table/utils/find-ordering-field.util.ts +++ b/backend/src/entities/table/utils/find-ordering-field.util.ts @@ -1,54 +1,54 @@ -import { TableSettingsEntity } from '../../table-settings/common-table-settings/table-settings.entity.js'; -import { OrderingFiledDs } from '../application/data-structures/found-table-rows.ds.js'; import { HttpException, HttpStatus } from '@nestjs/common'; -import { Messages } from '../../../exceptions/text/messages.js'; -import { QueryOrderingEnum } from '../../../enums/index.js'; import { TableStructureDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/table-structure.ds.js'; +import { QueryOrderingEnum } from '../../../enums/index.js'; +import { Messages } from '../../../exceptions/text/messages.js'; import { isObjectPropertyExists } from '../../../helpers/validators/is-object-property-exists-validator.js'; +import { TableSettingsEntity } from '../../table-settings/common-table-settings/table-settings.entity.js'; +import { OrderingFiledDs } from '../application/data-structures/found-table-rows.ds.js'; export function findOrderingFieldUtil( - query: Record, - tableStructure: Array, - tableSettings: TableSettingsEntity, + query: Record, + tableStructure: Array, + tableSettings: TableSettingsEntity, ): OrderingFiledDs | undefined { - if (!isObjectPropertyExists(query, 'sort_by') || !isObjectPropertyExists(query, 'sort_order')) { - return undefined; - } + if (!isObjectPropertyExists(query, 'sort_by') || !isObjectPropertyExists(query, 'sort_order')) { + return undefined; + } - const sortByFieldName = query.sort_by as string; - const sortByOrder = query.sort_order as QueryOrderingEnum; + const sortByFieldName = query.sort_by as string; + const sortByOrder = query.sort_order as QueryOrderingEnum; - const rowNames = new Set(tableStructure.map((el) => el.column_name)); + const rowNames = new Set(tableStructure.map((el) => el.column_name)); - if (!rowNames.has(sortByFieldName)) { - throw new HttpException( - { - message: Messages.EXCLUDED_OR_NOT_EXISTS(sortByFieldName), - }, - HttpStatus.BAD_REQUEST, - ); - } + if (!rowNames.has(sortByFieldName)) { + throw new HttpException( + { + message: Messages.EXCLUDED_OR_NOT_EXISTS(sortByFieldName), + }, + HttpStatus.BAD_REQUEST, + ); + } - if (tableSettings?.sortable_by?.length && !tableSettings.sortable_by.includes(sortByFieldName)) { - throw new HttpException( - { - message: Messages.FIELD_MUST_BE_SORTABLE(sortByFieldName), - }, - HttpStatus.BAD_REQUEST, - ); - } + if (tableSettings?.sortable_by?.length && !tableSettings.sortable_by.includes(sortByFieldName)) { + throw new HttpException( + { + message: Messages.FIELD_MUST_BE_SORTABLE(sortByFieldName), + }, + HttpStatus.BAD_REQUEST, + ); + } - if (!Object.values(QueryOrderingEnum).includes(sortByOrder)) { - throw new HttpException( - { - message: Messages.ORDERING_FIELD_INCORRECT, - }, - HttpStatus.BAD_REQUEST, - ); - } + if (!Object.values(QueryOrderingEnum).includes(sortByOrder)) { + throw new HttpException( + { + message: Messages.ORDERING_FIELD_INCORRECT, + }, + HttpStatus.BAD_REQUEST, + ); + } - return { - field: sortByFieldName, - value: sortByOrder, - }; + return { + field: sortByFieldName, + value: sortByOrder, + }; } diff --git a/backend/src/entities/table/utils/find-table-fields.util.ts b/backend/src/entities/table/utils/find-table-fields.util.ts index 5c301f3b0..478082bf2 100644 --- a/backend/src/entities/table/utils/find-table-fields.util.ts +++ b/backend/src/entities/table/utils/find-table-fields.util.ts @@ -1,13 +1,13 @@ -import { ConnectionEntity } from '../../connection/connection.entity.js'; import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; +import { ConnectionEntity } from '../../connection/connection.entity.js'; export async function findTableFieldsUtil( - connection: ConnectionEntity, - tableName: string, - _userId: string, - userEmail = 'unknown', + connection: ConnectionEntity, + tableName: string, + _userId: string, + userEmail = 'unknown', ): Promise> { - const dao = getDataAccessObject(connection); - const tableStructure = await dao.getTableStructure(tableName, userEmail); - return tableStructure.map((el) => el.column_name); + const dao = getDataAccessObject(connection); + const tableStructure = await dao.getTableStructure(tableName, userEmail); + return tableStructure.map((el) => el.column_name); } diff --git a/backend/src/entities/table/utils/find-tables-in-connection.util.ts b/backend/src/entities/table/utils/find-tables-in-connection.util.ts index 6756e8f8d..75cfff59c 100644 --- a/backend/src/entities/table/utils/find-tables-in-connection.util.ts +++ b/backend/src/entities/table/utils/find-tables-in-connection.util.ts @@ -1,12 +1,12 @@ -import { ConnectionEntity } from '../../connection/connection.entity.js'; import { getDataAccessObject } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/create-data-access-object.js'; +import { ConnectionEntity } from '../../connection/connection.entity.js'; export async function findTablesInConnectionUtil( - connection: ConnectionEntity, - _userId: string, - userEmail = 'unknown', + connection: ConnectionEntity, + _userId: string, + userEmail = 'unknown', ): Promise> { - const dao = getDataAccessObject(connection); - const tables = await dao.getTablesFromDB(userEmail); - return tables.map((table) => table.tableName); + const dao = getDataAccessObject(connection); + const tables = await dao.getTablesFromDB(userEmail); + return tables.map((table) => table.tableName); } diff --git a/backend/src/entities/table/utils/form-full-table-structure.ts b/backend/src/entities/table/utils/form-full-table-structure.ts index c5a2c9863..808f9bdbf 100644 --- a/backend/src/entities/table/utils/form-full-table-structure.ts +++ b/backend/src/entities/table/utils/form-full-table-structure.ts @@ -1,25 +1,25 @@ +import { TableStructureDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/table-structure.ds.js'; +import { checkFieldAutoincrement } from '../../../helpers/index.js'; import { TableSettingsEntity } from '../../table-settings/common-table-settings/table-settings.entity.js'; import { FullTableStructureDs } from '../application/data-structures/found-table-structure.ds.js'; -import { checkFieldAutoincrement } from '../../../helpers/index.js'; -import { TableStructureDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/table-structure.ds.js'; export function formFullTableStructure( - structure: Array, - tableSettings: TableSettingsEntity, + structure: Array, + tableSettings: TableSettingsEntity, ): Array { - const { search_fields, excluded_fields } = tableSettings || {}; + const { search_fields, excluded_fields } = tableSettings || {}; - return structure.map( - ({ column_name, column_default, data_type, data_type_params, allow_null, character_maximum_length, extra }) => ({ - column_name, - column_default, - data_type, - data_type_params: data_type_params || undefined, - isExcluded: excluded_fields?.includes(column_name) || false, - isSearched: search_fields?.includes(column_name) || false, - auto_increment: checkFieldAutoincrement(column_default, extra), - allow_null, - character_maximum_length, - }), - ); + return structure.map( + ({ column_name, column_default, data_type, data_type_params, allow_null, character_maximum_length, extra }) => ({ + column_name, + column_default, + data_type, + data_type_params: data_type_params || undefined, + isExcluded: excluded_fields?.includes(column_name) || false, + isSearched: search_fields?.includes(column_name) || false, + auto_increment: checkFieldAutoincrement(column_default, extra), + allow_null, + character_maximum_length, + }), + ); } diff --git a/backend/src/entities/table/utils/hash-passwords-in-row.util.ts b/backend/src/entities/table/utils/hash-passwords-in-row.util.ts index ffeab9d11..6896fc7be 100644 --- a/backend/src/entities/table/utils/hash-passwords-in-row.util.ts +++ b/backend/src/entities/table/utils/hash-passwords-in-row.util.ts @@ -1,34 +1,34 @@ -import { TableWidgetEntity } from '../../widget/table-widget.entity.js'; +import JSON5 from 'json5'; import { WidgetTypeEnum } from '../../../enums/index.js'; -import { IPasswordWidgetParams } from '../../widget/table-widget.interface.js'; -import { Encryptor } from '../../../helpers/encryption/encryptor.js'; import { Constants } from '../../../helpers/constants/constants.js'; -import JSON5 from 'json5'; +import { Encryptor } from '../../../helpers/encryption/encryptor.js'; +import { TableWidgetEntity } from '../../widget/table-widget.entity.js'; +import { IPasswordWidgetParams } from '../../widget/table-widget.interface.js'; export async function hashPasswordsInRowUtil( - row: Record, - tableWidgets: Array, + row: Record, + tableWidgets: Array, ): Promise> { - const passwordWidgets = tableWidgets?.filter((widget) => widget.widget_type === WidgetTypeEnum.Password) || []; + const passwordWidgets = tableWidgets?.filter((widget) => widget.widget_type === WidgetTypeEnum.Password) || []; - for (const widget of passwordWidgets) { - try { - const widgetParams = JSON5.parse(widget.widget_params) as unknown as IPasswordWidgetParams; - const fieldValue = row[widget.field_name]; + for (const widget of passwordWidgets) { + try { + const widgetParams = JSON5.parse(widget.widget_params) as unknown as IPasswordWidgetParams; + const fieldValue = row[widget.field_name]; - // Skip processing if the field value is the removed password placeholder - if (fieldValue === Constants.REMOVED_PASSWORD_VALUE) { - delete row[widget.field_name]; - continue; - } + // Skip processing if the field value is the removed password placeholder + if (fieldValue === Constants.REMOVED_PASSWORD_VALUE) { + delete row[widget.field_name]; + continue; + } - if (fieldValue !== undefined && fieldValue !== null && fieldValue !== '' && widgetParams.encrypt) { - row[widget.field_name] = await Encryptor.processDataWithAlgorithm(fieldValue as any, widgetParams.algorithm); - } - } catch (e) { - console.log('-> Error in password widget encryption processing', e); - } - } + if (fieldValue !== undefined && fieldValue !== null && fieldValue !== '' && widgetParams.encrypt) { + row[widget.field_name] = await Encryptor.processDataWithAlgorithm(fieldValue as any, widgetParams.algorithm); + } + } catch (e) { + console.log('-> Error in password widget encryption processing', e); + } + } - return row; + return row; } diff --git a/backend/src/entities/table/utils/is-hex-string.ts b/backend/src/entities/table/utils/is-hex-string.ts index befef7e6e..22455aa98 100644 --- a/backend/src/entities/table/utils/is-hex-string.ts +++ b/backend/src/entities/table/utils/is-hex-string.ts @@ -1,4 +1,4 @@ export function isHexString(hStr: string): boolean { - const re = /[0-9A-Fa-f]{6}/g; - return re.test(hStr); + const re = /[0-9A-Fa-f]{6}/g; + return re.test(hStr); } diff --git a/backend/src/entities/table/utils/process-found-rows-util.ts b/backend/src/entities/table/utils/process-found-rows-util.ts index f29f6688f..63554674f 100644 --- a/backend/src/entities/table/utils/process-found-rows-util.ts +++ b/backend/src/entities/table/utils/process-found-rows-util.ts @@ -1,66 +1,66 @@ import { TableStructureDS } from '@rocketadmin/shared-code/dist/src/data-access-layer/shared/data-structures/table-structure.ds.js'; import { FoundRowsDS } from '@rocketadmin/shared-code/src/data-access-layer/shared/data-structures/found-rows.ds.js'; +import sjson from 'secure-json-parse'; import { WidgetTypeEnum } from '../../../enums/widget-type.enum.js'; -import { isBinary, binaryToHex } from '../../../helpers/binary-to-hex.js'; +import { binaryToHex, isBinary } from '../../../helpers/binary-to-hex.js'; import { Constants } from '../../../helpers/constants/constants.js'; import { getPropertyValueByDescriptor } from '../../../helpers/get-property-value-by-descriptor.js'; import { getValuesBetweenCurlies, replaceTextInCurlies } from '../../../helpers/operate-values-between-curlies.js'; +import { isObjectPropertyExists } from '../../../helpers/validators/is-object-property-exists-validator.js'; import { CustomFieldsEntity } from '../../custom-field/custom-fields.entity.js'; import { TableWidgetEntity } from '../../widget/table-widget.entity.js'; -import sjson from 'secure-json-parse'; -import { isObjectPropertyExists } from '../../../helpers/validators/is-object-property-exists-validator.js'; export function processRowsUtil( - rows: FoundRowsDS, - tableWidgets: Array, - structure: Array, - customTableFields: Array, + rows: FoundRowsDS, + tableWidgets: Array, + structure: Array, + customTableFields: Array, ): FoundRowsDS { - const passwordWidgets = tableWidgets?.filter((el) => el.widget_type === WidgetTypeEnum.Password); - const binaryColumns = structure?.filter((el) => isBinary(el.data_type)); + const passwordWidgets = tableWidgets?.filter((el) => el.widget_type === WidgetTypeEnum.Password); + const binaryColumns = structure?.filter((el) => isBinary(el.data_type)); - const parsedRows: FoundRowsDS = sjson.parse(JSON.stringify(rows), null, { - protoAction: 'remove', - constructorAction: 'remove', - }); + const parsedRows: FoundRowsDS = sjson.parse(JSON.stringify(rows), null, { + protoAction: 'remove', + constructorAction: 'remove', + }); - parsedRows.data = parsedRows.data.map((row: Record) => { - if (customTableFields && customTableFields.length > 0) { - const customFields = customTableFields.map((field) => { - const fieldNamesFromTemplateString = getValuesBetweenCurlies(field.template_string); - const fieldValuesForTemplateString = fieldNamesFromTemplateString - .filter((fieldName) => isObjectPropertyExists(row, fieldName) && getPropertyValueByDescriptor(row, fieldName)) - .map((fieldName) => getPropertyValueByDescriptor(row, fieldName)); + parsedRows.data = parsedRows.data.map((row: Record) => { + if (customTableFields && customTableFields.length > 0) { + const customFields = customTableFields.map((field) => { + const fieldNamesFromTemplateString = getValuesBetweenCurlies(field.template_string); + const fieldValuesForTemplateString = fieldNamesFromTemplateString + .filter((fieldName) => isObjectPropertyExists(row, fieldName) && getPropertyValueByDescriptor(row, fieldName)) + .map((fieldName) => getPropertyValueByDescriptor(row, fieldName)); - const generatedUrlString = replaceTextInCurlies( - field.template_string, - fieldNamesFromTemplateString, - fieldValuesForTemplateString, - ); + const generatedUrlString = replaceTextInCurlies( + field.template_string, + fieldNamesFromTemplateString, + fieldValuesForTemplateString, + ); - return { - type: field.type, - url_template: generatedUrlString, - text: field.text, - }; - }); - row['#autoadmin:customFields'] = customFields; - } + return { + type: field.type, + url_template: generatedUrlString, + text: field.text, + }; + }); + row['#autoadmin:customFields'] = customFields; + } - binaryColumns?.forEach((column) => { - if (row[column.column_name]) { - row[column.column_name] = binaryToHex(row[column.column_name] as string); - } - }); + binaryColumns?.forEach((column) => { + if (row[column.column_name]) { + row[column.column_name] = binaryToHex(row[column.column_name] as string); + } + }); - passwordWidgets?.forEach((widget) => { - if (row[widget.field_name]) { - row[widget.field_name] = Constants.REMOVED_PASSWORD_VALUE; - } - }); + passwordWidgets?.forEach((widget) => { + if (row[widget.field_name]) { + row[widget.field_name] = Constants.REMOVED_PASSWORD_VALUE; + } + }); - return row; - }); + return row; + }); - return parsedRows; + return parsedRows; } diff --git a/backend/src/entities/table/utils/process-uuids-in-row-util.ts b/backend/src/entities/table/utils/process-uuids-in-row-util.ts index 7da0d33ec..0c212dcc9 100644 --- a/backend/src/entities/table/utils/process-uuids-in-row-util.ts +++ b/backend/src/entities/table/utils/process-uuids-in-row-util.ts @@ -1,24 +1,24 @@ -import { TableWidgetEntity } from '../../widget/table-widget.entity.js'; -import { WidgetTypeEnum } from '../../../enums/index.js'; -import { stringify as uuidStringify } from 'uuid'; import JSON5 from 'json5'; +import { stringify as uuidStringify } from 'uuid'; +import { WidgetTypeEnum } from '../../../enums/index.js'; +import { TableWidgetEntity } from '../../widget/table-widget.entity.js'; export function processUuidsInRowUtil( - row: Record, - tableWidgets: Array, + row: Record, + tableWidgets: Array, ): Record { - const uuidWidgets = tableWidgets?.filter((widget) => widget.widget_type === WidgetTypeEnum.UUID) || []; + const uuidWidgets = tableWidgets?.filter((widget) => widget.widget_type === WidgetTypeEnum.UUID) || []; - for (const widget of uuidWidgets) { - try { - const widgetParams = JSON5.parse(widget.widget_params); - if (row[widget.field_name] && Buffer.isBuffer(widgetParams)) { - row[widget.field_name] = uuidStringify(widgetParams); - } - } catch (e) { - console.error('-> Error in UUID widget processing', e); - } - } + for (const widget of uuidWidgets) { + try { + const widgetParams = JSON5.parse(widget.widget_params); + if (row[widget.field_name] && Buffer.isBuffer(widgetParams)) { + row[widget.field_name] = uuidStringify(widgetParams); + } + } catch (e) { + console.error('-> Error in UUID widget processing', e); + } + } - return row; + return row; } diff --git a/backend/src/entities/table/utils/remove-password-from-row.util.ts b/backend/src/entities/table/utils/remove-password-from-row.util.ts index 26a1310e7..dca65b203 100644 --- a/backend/src/entities/table/utils/remove-password-from-row.util.ts +++ b/backend/src/entities/table/utils/remove-password-from-row.util.ts @@ -1,18 +1,18 @@ -import { TableWidgetEntity } from '../../widget/table-widget.entity.js'; import { WidgetTypeEnum } from '../../../enums/index.js'; import { Constants } from '../../../helpers/constants/constants.js'; +import { TableWidgetEntity } from '../../widget/table-widget.entity.js'; export function removePasswordsFromRowsUtil( - row: Record, - tableWidgets: Array, + row: Record, + tableWidgets: Array, ): Record { - const passwordWidgets = tableWidgets?.filter((widget) => widget.widget_type === WidgetTypeEnum.Password) || []; + const passwordWidgets = tableWidgets?.filter((widget) => widget.widget_type === WidgetTypeEnum.Password) || []; - for (const widget of passwordWidgets) { - if (row[widget.field_name]) { - row[widget.field_name] = Constants.REMOVED_PASSWORD_VALUE; - } - } + for (const widget of passwordWidgets) { + if (row[widget.field_name]) { + row[widget.field_name] = Constants.REMOVED_PASSWORD_VALUE; + } + } - return row; + return row; } diff --git a/backend/src/entities/table/utils/save-tables-info-in-database.util.ts b/backend/src/entities/table/utils/save-tables-info-in-database.util.ts index 226ab1545..da76184a1 100644 --- a/backend/src/entities/table/utils/save-tables-info-in-database.util.ts +++ b/backend/src/entities/table/utils/save-tables-info-in-database.util.ts @@ -4,27 +4,27 @@ import { TableFieldInfoEntity } from '../../table-field-info/table-field-info.en import { TableInfoEntity } from '../../table-info/table-info.entity.js'; export function buildTableFieldInfoEntity( - structure: TableStructureDS, - tableInfo: TableInfoEntity, + structure: TableStructureDS, + tableInfo: TableInfoEntity, ): TableFieldInfoEntity { - const newTableFieldInfoEntity = new TableFieldInfoEntity(); - newTableFieldInfoEntity.column_name = structure.column_name; - newTableFieldInfoEntity.data_type = structure.data_type; - if (structure.character_maximum_length) { - newTableFieldInfoEntity.character_maximum_length = structure.character_maximum_length.toString(); - } - newTableFieldInfoEntity.allow_null = structure.allow_null; - newTableFieldInfoEntity.column_default = structure.column_default; - newTableFieldInfoEntity.data_type_params = structure.data_type_params; - newTableFieldInfoEntity.udt_name = structure.udt_name; - newTableFieldInfoEntity.table_info = tableInfo; - return newTableFieldInfoEntity; + const newTableFieldInfoEntity = new TableFieldInfoEntity(); + newTableFieldInfoEntity.column_name = structure.column_name; + newTableFieldInfoEntity.data_type = structure.data_type; + if (structure.character_maximum_length) { + newTableFieldInfoEntity.character_maximum_length = structure.character_maximum_length.toString(); + } + newTableFieldInfoEntity.allow_null = structure.allow_null; + newTableFieldInfoEntity.column_default = structure.column_default; + newTableFieldInfoEntity.data_type_params = structure.data_type_params; + newTableFieldInfoEntity.udt_name = structure.udt_name; + newTableFieldInfoEntity.table_info = tableInfo; + return newTableFieldInfoEntity; } export function buildTableInfoEntity(tableName: string, connection: ConnectionEntity): TableInfoEntity { - const newTableInfoEntity = new TableInfoEntity(); - newTableInfoEntity.table_name = tableName; - newTableInfoEntity.connection = connection; - newTableInfoEntity.table_fields_info = []; - return newTableInfoEntity; + const newTableInfoEntity = new TableInfoEntity(); + newTableInfoEntity.table_name = tableName; + newTableInfoEntity.connection = connection; + newTableInfoEntity.table_fields_info = []; + return newTableInfoEntity; } diff --git a/backend/src/entities/table/utils/validate-table-row.util.ts b/backend/src/entities/table/utils/validate-table-row.util.ts index 41104f5b2..d25316bda 100644 --- a/backend/src/entities/table/utils/validate-table-row.util.ts +++ b/backend/src/entities/table/utils/validate-table-row.util.ts @@ -2,26 +2,22 @@ import { TableStructureDS } from '@rocketadmin/shared-code/dist/src/data-access- import { Messages } from '../../../exceptions/text/messages.js'; export function validateTableRowUtil(row: Record, structure: Array): Array { - const errors = []; - const keys = Object.keys(row); - keys.map((key) => { - key.toLowerCase(); - }); + const errors = []; + const keys = Object.keys(row); + keys.map((key) => { + key.toLowerCase(); + }); - for (let i = 0; i < structure.length; i++) { - try { - const index = keys.indexOf(structure.at(i).column_name); - if ( - (index >= 0 && - structure.at(i).column_default != null && - structure.at(i).column_default.includes('nextval')) || - (index >= 0 && - structure.at(i).column_default != null && - structure.at(i).column_default.includes('generate')) - ) { - errors.push(Messages.CANNOT_ADD_AUTOGENERATED_VALUE); - } - } catch (_e) {} - } - return errors; + for (let i = 0; i < structure.length; i++) { + try { + const index = keys.indexOf(structure.at(i).column_name); + if ( + (index >= 0 && structure.at(i).column_default != null && structure.at(i).column_default.includes('nextval')) || + (index >= 0 && structure.at(i).column_default != null && structure.at(i).column_default.includes('generate')) + ) { + errors.push(Messages.CANNOT_ADD_AUTOGENERATED_VALUE); + } + } catch (_e) {} + } + return errors; } diff --git a/backend/src/entities/user-access/repository/user-access-custom-repository-extension.ts b/backend/src/entities/user-access/repository/user-access-custom-repository-extension.ts index 831ea2527..e2dc2c03b 100644 --- a/backend/src/entities/user-access/repository/user-access-custom-repository-extension.ts +++ b/backend/src/entities/user-access/repository/user-access-custom-repository-extension.ts @@ -1,473 +1,473 @@ import { HttpException, HttpStatus } from '@nestjs/common'; import { AccessLevelEnum, PermissionTypeEnum } from '../../../enums/index.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { Cacher } from '../../../helpers/cache/cacher.js'; import { ConnectionEntity } from '../../connection/connection.entity.js'; import { PermissionEntity } from '../../permission/permission.entity.js'; import { ITablePermissionData } from '../../permission/permission.interface.js'; -import { IUserAccessRepository } from './user-access.repository.interface.js'; -import { Cacher } from '../../../helpers/cache/cacher.js'; import { UserEntity } from '../../user/user.entity.js'; +import { IUserAccessRepository } from './user-access.repository.interface.js'; export const userAccessCustomReposiotoryExtension: IUserAccessRepository = { - async getUserConnectionAccessLevel(cognitoUserName: string, connectionId: string): Promise { - const qb = this.createQueryBuilder('permission') - .leftJoin('permission.groups', 'group') - .leftJoin('group.users', 'user') - .leftJoin('group.connection', 'connection') - .where( - 'connection.id = :connectionId AND user.id = :cognitoUserName AND user.suspended = :isSuspended AND permission.type = :permissionType', - { - connectionId, - cognitoUserName, - isSuspended: false, - permissionType: PermissionTypeEnum.Connection, - }, - ); - - const resultPermissions = await qb.getMany(); - - if (resultPermissions.length === 0) { - const isUserSuspended = !!(await this.manager - .getRepository(UserEntity) - .createQueryBuilder('user') - .where('user.id = :cognitoUserName AND user.suspended = :isSuspended', { - cognitoUserName, - isSuspended: true, - }) - .getCount()); - - if (isUserSuspended) { - throw new HttpException( - { - message: Messages.ACCOUNT_SUSPENDED, - }, - HttpStatus.FORBIDDEN, - ); - } - return AccessLevelEnum.none; - } - - for (const permission of resultPermissions) { - if (permission.accessLevel === AccessLevelEnum.edit) { - return AccessLevelEnum.edit; - } - } - - for (const permission of resultPermissions) { - if (permission.accessLevel === AccessLevelEnum.readonly) { - return AccessLevelEnum.readonly; - } - } - return AccessLevelEnum.none; - }, - - async checkUserConnectionRead(cognitoUserName: string, connectionId: string): Promise { - const connectionAccessLevel = await this.getUserConnectionAccessLevel(cognitoUserName, connectionId); - return connectionAccessLevel === AccessLevelEnum.edit || connectionAccessLevel === AccessLevelEnum.readonly; - }, - - async checkUserConnectionEdit(cognitoUserName: string, connectionId: string): Promise { - const connectionAccessLevel = await this.getUserConnectionAccessLevel(cognitoUserName, connectionId); - return connectionAccessLevel === AccessLevelEnum.edit; - }, - - async getGroupAccessLevel(cognitoUserName: string, groupId: string): Promise { - const connectionId = await this.getConnectionId(groupId); - - const connectionEdit = !!(await this.createQueryBuilder('permission') - .leftJoin('permission.groups', 'group') - .leftJoin('group.users', 'user') - .leftJoin('group.connection', 'connection') - .where( - 'connection.id = :connectionId AND user.id = :cognitoUserName AND user.suspended = :isSuspended AND permission.type = :permissionType AND permission.accessLevel = :accessLevel', - { - connectionId, - cognitoUserName, - isSuspended: false, - permissionType: PermissionTypeEnum.Connection, - accessLevel: AccessLevelEnum.edit, - }, - ) - .getCount()); - - if (connectionEdit) { - return AccessLevelEnum.edit; - } - const qb = this.createQueryBuilder('permission') - .leftJoin('permission.groups', 'group') - .leftJoin('group.users', 'user') - .leftJoin('group.connection', 'connection') - .where( - 'connection.id = :connectionId AND user.id = :cognitoUserName AND user.suspended = :isSuspended AND permission.type = :permissionType AND group.id = :groupId', - { - connectionId, - cognitoUserName, - isSuspended: false, - permissionType: PermissionTypeEnum.Group, - groupId, - }, - ); - - const resultPermissions = await qb.getMany(); - - if (resultPermissions.length === 0) { - const isUserSuspended = !!(await this.manager - .getRepository(UserEntity) - .createQueryBuilder('user') - .where('user.id = :cognitoUserName AND user.suspended = :isSuspended', { - cognitoUserName, - isSuspended: true, - }) - .getCount()); - - if (isUserSuspended) { - throw new HttpException( - { - message: Messages.ACCOUNT_SUSPENDED, - }, - HttpStatus.FORBIDDEN, - ); - } - return AccessLevelEnum.none; - } - - const connectionAccessLevels = resultPermissions.map((permission: PermissionEntity) => { - return permission.accessLevel.toLowerCase(); - }); - - if (connectionAccessLevels.includes(AccessLevelEnum.edit)) { - return AccessLevelEnum.edit; - } - - if (connectionAccessLevels.includes(AccessLevelEnum.readonly)) { - return AccessLevelEnum.readonly; - } - - return AccessLevelEnum.none; - }, - - async checkUserGroupRead(cognitoUserName: string, groupId: string): Promise { - const userGroupAccessLevel = await this.getGroupAccessLevel(cognitoUserName, groupId); - return userGroupAccessLevel === AccessLevelEnum.edit || userGroupAccessLevel === AccessLevelEnum.readonly; - }, - - async checkUserGroupEdit(cognitoUserName: string, groupId: string): Promise { - const userGroupAccessLevel = await this.getGroupAccessLevel(cognitoUserName, groupId); - return userGroupAccessLevel === AccessLevelEnum.edit; - }, - - async getUserTablePermissions( - cognitoUserName: string, - connectionId: string, - tableName: string, - _masterPwd: string, - ): Promise { - const connectionEdit = !!(await this.createQueryBuilder('permission') - .leftJoin('permission.groups', 'group') - .leftJoin('group.users', 'user') - .leftJoin('group.connection', 'connection') - .where( - 'connection.id = :connectionId AND user.id = :cognitoUserName AND user.suspended = :isSuspended AND permission.type = :permissionType AND permission.accessLevel = :accessLevel', - { - connectionId, - cognitoUserName, - isSuspended: false, - permissionType: PermissionTypeEnum.Connection, - accessLevel: AccessLevelEnum.edit, - }, - ) - .getCount()); - - if (connectionEdit) { - return { - tableName: tableName, - accessLevel: { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: true, - }, - }; - } - - const qb = this.createQueryBuilder('permission') - .leftJoin('permission.groups', 'group') - .leftJoin('group.users', 'user') - .leftJoin('group.connection', 'connection') - .where( - 'connection.id = :connectionId AND user.id = :cognitoUserName AND user.suspended = :isSuspended AND permission.type = :permissionType AND permission.tableName = :tableName', - { - connectionId, - cognitoUserName, - isSuspended: false, - permissionType: PermissionTypeEnum.Table, - tableName, - }, - ); - - const resultPermissions: Array = await qb.getMany(); - - if (resultPermissions.length === 0) { - const isUserSuspended = !!(await this.manager - .getRepository(UserEntity) - .createQueryBuilder('user') - .where('user.id = :cognitoUserName AND user.suspended = :isSuspended', { - cognitoUserName, - isSuspended: true, - }) - .getCount()); - - if (isUserSuspended) { - throw new HttpException( - { - message: Messages.ACCOUNT_SUSPENDED, - }, - HttpStatus.FORBIDDEN, - ); - } - } - - const accessLevels = { - visibility: false, - readonly: false, - add: false, - delete: false, - edit: false, - }; - - for (const permission of resultPermissions) { - switch (permission.accessLevel) { - case AccessLevelEnum.visibility: - accessLevels.visibility = true; - break; - case AccessLevelEnum.readonly: - accessLevels.readonly = true; - break; - case AccessLevelEnum.add: - accessLevels.add = true; - break; - case AccessLevelEnum.delete: - accessLevels.delete = true; - break; - case AccessLevelEnum.edit: - accessLevels.edit = true; - break; - } - } - - return { - tableName: tableName, - accessLevel: accessLevels, - }; - }, - - async getUserPermissionsForAvailableTables( - cognitoUserName: string, - connectionId: string, - tableNames: Array, - ): Promise> { - const connectionEdit = !!(await this.createQueryBuilder('permission') - .leftJoin('permission.groups', 'group') - .leftJoin('group.users', 'user') - .leftJoin('group.connection', 'connection') - .where( - 'connection.id = :connectionId AND user.id = :cognitoUserName AND permission.type = :permissionType AND permission.accessLevel = :accessLevel', - { - connectionId, - cognitoUserName, - permissionType: PermissionTypeEnum.Connection, - accessLevel: AccessLevelEnum.edit, - }, - ) - .getCount()); - - const tablesWithPermissionsArr = []; - if (connectionEdit) { - for (const tableName of tableNames) { - tablesWithPermissionsArr.push({ - tableName: tableName, - accessLevel: { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: true, - }, - }); - } - return tablesWithPermissionsArr; - } - - const qb = this.createQueryBuilder('permission') - .leftJoin('permission.groups', 'group') - .leftJoin('group.users', 'user') - .leftJoin('group.connection', 'connection') - .where( - 'connection.id = :connectionId AND user.id = :cognitoUserName AND user.suspended = :isSuspended AND permission.type = :permissionType', - { - connectionId, - cognitoUserName, - isSuspended: false, - permissionType: PermissionTypeEnum.Table, - }, - ); - - const allTablePermissions: Array = await qb.getMany(); - - if (allTablePermissions.length === 0) { - const isUserSuspended = !!(await this.manager - .getRepository(UserEntity) - .createQueryBuilder('user') - .where('user.id = :cognitoUserName AND user.suspended = :isSuspended', { - cognitoUserName, - isSuspended: true, - }) - .getCount()); - - if (isUserSuspended) { - throw new HttpException( - { - message: Messages.ACCOUNT_SUSPENDED, - }, - HttpStatus.FORBIDDEN, - ); - } - } - - const tablesAndAccessLevels = new Map>(); - - for (const tableName of tableNames) { - if (tableName !== '__proto__') { - tablesAndAccessLevels.set(tableName, new Set()); - } - } - - for (const permission of allTablePermissions) { - const { tableName, accessLevel } = permission; - if (tablesAndAccessLevels.has(tableName)) { - tablesAndAccessLevels.get(tableName)!.add(accessLevel as AccessLevelEnum); - } - } - - for (const [tableName, accessLevels] of tablesAndAccessLevels) { - const accessLevelObj = { - visibility: accessLevels.has(AccessLevelEnum.visibility), - readonly: accessLevels.has(AccessLevelEnum.readonly), - add: accessLevels.has(AccessLevelEnum.add), - delete: accessLevels.has(AccessLevelEnum.delete), - edit: accessLevels.has(AccessLevelEnum.edit), - }; - - tablesWithPermissionsArr.push({ - tableName, - accessLevel: accessLevelObj, - }); - } - - return tablesWithPermissionsArr.filter((tableWithPermission: ITablePermissionData) => { - return tableWithPermission.accessLevel.visibility; - }); - }, - - async checkTableRead( - cognitoUserName: string, - connectionId: string, - tableName: string, - masterPwd: string, - ): Promise { - const { accessLevel } = await this.getUserTablePermissions(cognitoUserName, connectionId, tableName, masterPwd); - return accessLevel.visibility || accessLevel.add || accessLevel.delete || accessLevel.edit; - }, - - async checkTableAdd( - cognitoUserName: string, - connectionId: string, - tableName: string, - masterPwd: string, - ): Promise { - const { accessLevel } = await this.getUserTablePermissions(cognitoUserName, connectionId, tableName, masterPwd); - return accessLevel.visibility && accessLevel.add; - }, - - async checkTableDelete( - cognitoUserName: string, - connectionId: string, - tableName: string, - masterPwd: string, - ): Promise { - const { accessLevel } = await this.getUserTablePermissions(cognitoUserName, connectionId, tableName, masterPwd); - return accessLevel.visibility && accessLevel.delete; - }, - - async checkTableEdit( - cognitoUserName: string, - connectionId: string, - tableName: string, - masterPwd: string, - ): Promise { - const { accessLevel } = await this.getUserTablePermissions(cognitoUserName, connectionId, tableName, masterPwd); - return accessLevel.visibility && accessLevel.edit; - }, - - async getConnectionId(groupId: string): Promise { - const connectionRepository = this.manager.getRepository(ConnectionEntity); - const connection = await connectionRepository - .createQueryBuilder('connection') - .leftJoin('connection.groups', 'group') - .where('group.id = :id', { id: groupId }) - .getOne(); - - if (!connection) { - throw new HttpException({ message: Messages.CONNECTION_NOT_FOUND }, HttpStatus.BAD_REQUEST); - } - - return connection.id; - }, - - async improvedCheckTableRead(userId: string, connectionId: string, tableName: string): Promise { - const cachedReadPermission: boolean | null = Cacher.getUserTableReadPermissionCache( - userId, - connectionId, - tableName, - ); - if (cachedReadPermission !== null) { - return cachedReadPermission; - } - - const qb = this.createQueryBuilder('permission') - .leftJoin('permission.groups', 'group') - .leftJoin('group.users', 'user') - .leftJoin('group.connection', 'connection') - .where('connection.id = :connectionId AND user.id = :userId AND user.suspended = :isSuspended', { - connectionId, - userId, - isSuspended: false, - }); - - const allUserPermissions: Array = await qb.getMany(); - - if (allUserPermissions.length === 0) { - Cacher.setUserTableReadPermissionCache(userId, connectionId, tableName, false); - return false; - } - - const hasReadPermission = allUserPermissions.some( - (permission) => - (permission.type === PermissionTypeEnum.Connection && permission.accessLevel === AccessLevelEnum.edit) || - (permission.type === PermissionTypeEnum.Table && - permission.tableName === tableName && - [AccessLevelEnum.visibility, AccessLevelEnum.add, AccessLevelEnum.delete, AccessLevelEnum.edit].includes( - permission.accessLevel as AccessLevelEnum, - )), - ); - - if (hasReadPermission) { - Cacher.setUserTableReadPermissionCache(userId, connectionId, tableName, true); - return true; - } - - Cacher.setUserTableReadPermissionCache(userId, connectionId, tableName, false); - return false; - }, + async getUserConnectionAccessLevel(cognitoUserName: string, connectionId: string): Promise { + const qb = this.createQueryBuilder('permission') + .leftJoin('permission.groups', 'group') + .leftJoin('group.users', 'user') + .leftJoin('group.connection', 'connection') + .where( + 'connection.id = :connectionId AND user.id = :cognitoUserName AND user.suspended = :isSuspended AND permission.type = :permissionType', + { + connectionId, + cognitoUserName, + isSuspended: false, + permissionType: PermissionTypeEnum.Connection, + }, + ); + + const resultPermissions = await qb.getMany(); + + if (resultPermissions.length === 0) { + const isUserSuspended = !!(await this.manager + .getRepository(UserEntity) + .createQueryBuilder('user') + .where('user.id = :cognitoUserName AND user.suspended = :isSuspended', { + cognitoUserName, + isSuspended: true, + }) + .getCount()); + + if (isUserSuspended) { + throw new HttpException( + { + message: Messages.ACCOUNT_SUSPENDED, + }, + HttpStatus.FORBIDDEN, + ); + } + return AccessLevelEnum.none; + } + + for (const permission of resultPermissions) { + if (permission.accessLevel === AccessLevelEnum.edit) { + return AccessLevelEnum.edit; + } + } + + for (const permission of resultPermissions) { + if (permission.accessLevel === AccessLevelEnum.readonly) { + return AccessLevelEnum.readonly; + } + } + return AccessLevelEnum.none; + }, + + async checkUserConnectionRead(cognitoUserName: string, connectionId: string): Promise { + const connectionAccessLevel = await this.getUserConnectionAccessLevel(cognitoUserName, connectionId); + return connectionAccessLevel === AccessLevelEnum.edit || connectionAccessLevel === AccessLevelEnum.readonly; + }, + + async checkUserConnectionEdit(cognitoUserName: string, connectionId: string): Promise { + const connectionAccessLevel = await this.getUserConnectionAccessLevel(cognitoUserName, connectionId); + return connectionAccessLevel === AccessLevelEnum.edit; + }, + + async getGroupAccessLevel(cognitoUserName: string, groupId: string): Promise { + const connectionId = await this.getConnectionId(groupId); + + const connectionEdit = !!(await this.createQueryBuilder('permission') + .leftJoin('permission.groups', 'group') + .leftJoin('group.users', 'user') + .leftJoin('group.connection', 'connection') + .where( + 'connection.id = :connectionId AND user.id = :cognitoUserName AND user.suspended = :isSuspended AND permission.type = :permissionType AND permission.accessLevel = :accessLevel', + { + connectionId, + cognitoUserName, + isSuspended: false, + permissionType: PermissionTypeEnum.Connection, + accessLevel: AccessLevelEnum.edit, + }, + ) + .getCount()); + + if (connectionEdit) { + return AccessLevelEnum.edit; + } + const qb = this.createQueryBuilder('permission') + .leftJoin('permission.groups', 'group') + .leftJoin('group.users', 'user') + .leftJoin('group.connection', 'connection') + .where( + 'connection.id = :connectionId AND user.id = :cognitoUserName AND user.suspended = :isSuspended AND permission.type = :permissionType AND group.id = :groupId', + { + connectionId, + cognitoUserName, + isSuspended: false, + permissionType: PermissionTypeEnum.Group, + groupId, + }, + ); + + const resultPermissions = await qb.getMany(); + + if (resultPermissions.length === 0) { + const isUserSuspended = !!(await this.manager + .getRepository(UserEntity) + .createQueryBuilder('user') + .where('user.id = :cognitoUserName AND user.suspended = :isSuspended', { + cognitoUserName, + isSuspended: true, + }) + .getCount()); + + if (isUserSuspended) { + throw new HttpException( + { + message: Messages.ACCOUNT_SUSPENDED, + }, + HttpStatus.FORBIDDEN, + ); + } + return AccessLevelEnum.none; + } + + const connectionAccessLevels = resultPermissions.map((permission: PermissionEntity) => { + return permission.accessLevel.toLowerCase(); + }); + + if (connectionAccessLevels.includes(AccessLevelEnum.edit)) { + return AccessLevelEnum.edit; + } + + if (connectionAccessLevels.includes(AccessLevelEnum.readonly)) { + return AccessLevelEnum.readonly; + } + + return AccessLevelEnum.none; + }, + + async checkUserGroupRead(cognitoUserName: string, groupId: string): Promise { + const userGroupAccessLevel = await this.getGroupAccessLevel(cognitoUserName, groupId); + return userGroupAccessLevel === AccessLevelEnum.edit || userGroupAccessLevel === AccessLevelEnum.readonly; + }, + + async checkUserGroupEdit(cognitoUserName: string, groupId: string): Promise { + const userGroupAccessLevel = await this.getGroupAccessLevel(cognitoUserName, groupId); + return userGroupAccessLevel === AccessLevelEnum.edit; + }, + + async getUserTablePermissions( + cognitoUserName: string, + connectionId: string, + tableName: string, + _masterPwd: string, + ): Promise { + const connectionEdit = !!(await this.createQueryBuilder('permission') + .leftJoin('permission.groups', 'group') + .leftJoin('group.users', 'user') + .leftJoin('group.connection', 'connection') + .where( + 'connection.id = :connectionId AND user.id = :cognitoUserName AND user.suspended = :isSuspended AND permission.type = :permissionType AND permission.accessLevel = :accessLevel', + { + connectionId, + cognitoUserName, + isSuspended: false, + permissionType: PermissionTypeEnum.Connection, + accessLevel: AccessLevelEnum.edit, + }, + ) + .getCount()); + + if (connectionEdit) { + return { + tableName: tableName, + accessLevel: { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: true, + }, + }; + } + + const qb = this.createQueryBuilder('permission') + .leftJoin('permission.groups', 'group') + .leftJoin('group.users', 'user') + .leftJoin('group.connection', 'connection') + .where( + 'connection.id = :connectionId AND user.id = :cognitoUserName AND user.suspended = :isSuspended AND permission.type = :permissionType AND permission.tableName = :tableName', + { + connectionId, + cognitoUserName, + isSuspended: false, + permissionType: PermissionTypeEnum.Table, + tableName, + }, + ); + + const resultPermissions: Array = await qb.getMany(); + + if (resultPermissions.length === 0) { + const isUserSuspended = !!(await this.manager + .getRepository(UserEntity) + .createQueryBuilder('user') + .where('user.id = :cognitoUserName AND user.suspended = :isSuspended', { + cognitoUserName, + isSuspended: true, + }) + .getCount()); + + if (isUserSuspended) { + throw new HttpException( + { + message: Messages.ACCOUNT_SUSPENDED, + }, + HttpStatus.FORBIDDEN, + ); + } + } + + const accessLevels = { + visibility: false, + readonly: false, + add: false, + delete: false, + edit: false, + }; + + for (const permission of resultPermissions) { + switch (permission.accessLevel) { + case AccessLevelEnum.visibility: + accessLevels.visibility = true; + break; + case AccessLevelEnum.readonly: + accessLevels.readonly = true; + break; + case AccessLevelEnum.add: + accessLevels.add = true; + break; + case AccessLevelEnum.delete: + accessLevels.delete = true; + break; + case AccessLevelEnum.edit: + accessLevels.edit = true; + break; + } + } + + return { + tableName: tableName, + accessLevel: accessLevels, + }; + }, + + async getUserPermissionsForAvailableTables( + cognitoUserName: string, + connectionId: string, + tableNames: Array, + ): Promise> { + const connectionEdit = !!(await this.createQueryBuilder('permission') + .leftJoin('permission.groups', 'group') + .leftJoin('group.users', 'user') + .leftJoin('group.connection', 'connection') + .where( + 'connection.id = :connectionId AND user.id = :cognitoUserName AND permission.type = :permissionType AND permission.accessLevel = :accessLevel', + { + connectionId, + cognitoUserName, + permissionType: PermissionTypeEnum.Connection, + accessLevel: AccessLevelEnum.edit, + }, + ) + .getCount()); + + const tablesWithPermissionsArr = []; + if (connectionEdit) { + for (const tableName of tableNames) { + tablesWithPermissionsArr.push({ + tableName: tableName, + accessLevel: { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: true, + }, + }); + } + return tablesWithPermissionsArr; + } + + const qb = this.createQueryBuilder('permission') + .leftJoin('permission.groups', 'group') + .leftJoin('group.users', 'user') + .leftJoin('group.connection', 'connection') + .where( + 'connection.id = :connectionId AND user.id = :cognitoUserName AND user.suspended = :isSuspended AND permission.type = :permissionType', + { + connectionId, + cognitoUserName, + isSuspended: false, + permissionType: PermissionTypeEnum.Table, + }, + ); + + const allTablePermissions: Array = await qb.getMany(); + + if (allTablePermissions.length === 0) { + const isUserSuspended = !!(await this.manager + .getRepository(UserEntity) + .createQueryBuilder('user') + .where('user.id = :cognitoUserName AND user.suspended = :isSuspended', { + cognitoUserName, + isSuspended: true, + }) + .getCount()); + + if (isUserSuspended) { + throw new HttpException( + { + message: Messages.ACCOUNT_SUSPENDED, + }, + HttpStatus.FORBIDDEN, + ); + } + } + + const tablesAndAccessLevels = new Map>(); + + for (const tableName of tableNames) { + if (tableName !== '__proto__') { + tablesAndAccessLevels.set(tableName, new Set()); + } + } + + for (const permission of allTablePermissions) { + const { tableName, accessLevel } = permission; + if (tablesAndAccessLevels.has(tableName)) { + tablesAndAccessLevels.get(tableName)!.add(accessLevel as AccessLevelEnum); + } + } + + for (const [tableName, accessLevels] of tablesAndAccessLevels) { + const accessLevelObj = { + visibility: accessLevels.has(AccessLevelEnum.visibility), + readonly: accessLevels.has(AccessLevelEnum.readonly), + add: accessLevels.has(AccessLevelEnum.add), + delete: accessLevels.has(AccessLevelEnum.delete), + edit: accessLevels.has(AccessLevelEnum.edit), + }; + + tablesWithPermissionsArr.push({ + tableName, + accessLevel: accessLevelObj, + }); + } + + return tablesWithPermissionsArr.filter((tableWithPermission: ITablePermissionData) => { + return tableWithPermission.accessLevel.visibility; + }); + }, + + async checkTableRead( + cognitoUserName: string, + connectionId: string, + tableName: string, + masterPwd: string, + ): Promise { + const { accessLevel } = await this.getUserTablePermissions(cognitoUserName, connectionId, tableName, masterPwd); + return accessLevel.visibility || accessLevel.add || accessLevel.delete || accessLevel.edit; + }, + + async checkTableAdd( + cognitoUserName: string, + connectionId: string, + tableName: string, + masterPwd: string, + ): Promise { + const { accessLevel } = await this.getUserTablePermissions(cognitoUserName, connectionId, tableName, masterPwd); + return accessLevel.visibility && accessLevel.add; + }, + + async checkTableDelete( + cognitoUserName: string, + connectionId: string, + tableName: string, + masterPwd: string, + ): Promise { + const { accessLevel } = await this.getUserTablePermissions(cognitoUserName, connectionId, tableName, masterPwd); + return accessLevel.visibility && accessLevel.delete; + }, + + async checkTableEdit( + cognitoUserName: string, + connectionId: string, + tableName: string, + masterPwd: string, + ): Promise { + const { accessLevel } = await this.getUserTablePermissions(cognitoUserName, connectionId, tableName, masterPwd); + return accessLevel.visibility && accessLevel.edit; + }, + + async getConnectionId(groupId: string): Promise { + const connectionRepository = this.manager.getRepository(ConnectionEntity); + const connection = await connectionRepository + .createQueryBuilder('connection') + .leftJoin('connection.groups', 'group') + .where('group.id = :id', { id: groupId }) + .getOne(); + + if (!connection) { + throw new HttpException({ message: Messages.CONNECTION_NOT_FOUND }, HttpStatus.BAD_REQUEST); + } + + return connection.id; + }, + + async improvedCheckTableRead(userId: string, connectionId: string, tableName: string): Promise { + const cachedReadPermission: boolean | null = Cacher.getUserTableReadPermissionCache( + userId, + connectionId, + tableName, + ); + if (cachedReadPermission !== null) { + return cachedReadPermission; + } + + const qb = this.createQueryBuilder('permission') + .leftJoin('permission.groups', 'group') + .leftJoin('group.users', 'user') + .leftJoin('group.connection', 'connection') + .where('connection.id = :connectionId AND user.id = :userId AND user.suspended = :isSuspended', { + connectionId, + userId, + isSuspended: false, + }); + + const allUserPermissions: Array = await qb.getMany(); + + if (allUserPermissions.length === 0) { + Cacher.setUserTableReadPermissionCache(userId, connectionId, tableName, false); + return false; + } + + const hasReadPermission = allUserPermissions.some( + (permission) => + (permission.type === PermissionTypeEnum.Connection && permission.accessLevel === AccessLevelEnum.edit) || + (permission.type === PermissionTypeEnum.Table && + permission.tableName === tableName && + [AccessLevelEnum.visibility, AccessLevelEnum.add, AccessLevelEnum.delete, AccessLevelEnum.edit].includes( + permission.accessLevel as AccessLevelEnum, + )), + ); + + if (hasReadPermission) { + Cacher.setUserTableReadPermissionCache(userId, connectionId, tableName, true); + return true; + } + + Cacher.setUserTableReadPermissionCache(userId, connectionId, tableName, false); + return false; + }, }; diff --git a/backend/src/entities/user-access/repository/user-access.repository.interface.ts b/backend/src/entities/user-access/repository/user-access.repository.interface.ts index 15a28ff1f..4fdf6dc05 100644 --- a/backend/src/entities/user-access/repository/user-access.repository.interface.ts +++ b/backend/src/entities/user-access/repository/user-access.repository.interface.ts @@ -2,45 +2,45 @@ import { AccessLevelEnum } from '../../../enums/index.js'; import { ITablePermissionData } from '../../permission/permission.interface.js'; export interface IUserAccessRepository { - getUserConnectionAccessLevel(cognitoUserName: string, connectionId: string): Promise; + getUserConnectionAccessLevel(cognitoUserName: string, connectionId: string): Promise; - checkUserConnectionRead(cognitoUserName: string, connectionId: string): Promise; + checkUserConnectionRead(cognitoUserName: string, connectionId: string): Promise; - checkUserConnectionEdit(cognitoUserName: string, connectionId: string): Promise; + checkUserConnectionEdit(cognitoUserName: string, connectionId: string): Promise; - getGroupAccessLevel(cognitoUserName: string, groupId: string): Promise; + getGroupAccessLevel(cognitoUserName: string, groupId: string): Promise; - checkUserGroupRead(cognitoUserName: string, groupId: string): Promise; + checkUserGroupRead(cognitoUserName: string, groupId: string): Promise; - checkUserGroupEdit(cognitoUserName: string, groupId: string): Promise; + checkUserGroupEdit(cognitoUserName: string, groupId: string): Promise; - getUserTablePermissions( - cognitoUserName: string, - connectionId: string, - tableName: string, - masterPwd: string, - ): Promise; + getUserTablePermissions( + cognitoUserName: string, + connectionId: string, + tableName: string, + masterPwd: string, + ): Promise; - getUserPermissionsForAvailableTables( - cognitoUserName: string, - connectionId: string, - tableNames: Array, - ): Promise>; + getUserPermissionsForAvailableTables( + cognitoUserName: string, + connectionId: string, + tableNames: Array, + ): Promise>; - checkTableRead(cognitoUserName: string, connectionId: string, tableName: string, masterPwd: string): Promise; + checkTableRead(cognitoUserName: string, connectionId: string, tableName: string, masterPwd: string): Promise; - checkTableAdd(cognitoUserName: string, connectionId: string, tableName: string, masterPwd: string): Promise; + checkTableAdd(cognitoUserName: string, connectionId: string, tableName: string, masterPwd: string): Promise; - checkTableDelete( - cognitoUserName: string, - connectionId: string, - tableName: string, - masterPwd: string, - ): Promise; + checkTableDelete( + cognitoUserName: string, + connectionId: string, + tableName: string, + masterPwd: string, + ): Promise; - checkTableEdit(cognitoUserName: string, connectionId: string, tableName: string, masterPwd: string): Promise; + checkTableEdit(cognitoUserName: string, connectionId: string, tableName: string, masterPwd: string): Promise; - getConnectionId(groupId: string): Promise; + getConnectionId(groupId: string): Promise; - improvedCheckTableRead(userId: string, connectionId: string, tableName: string, masterPwd?: string): Promise; + improvedCheckTableRead(userId: string, connectionId: string, tableName: string, masterPwd?: string): Promise; } diff --git a/backend/src/entities/user-actions/application/data-sctructures/create-user-action.ds.ts b/backend/src/entities/user-actions/application/data-sctructures/create-user-action.ds.ts index d7debbccf..fe7040daa 100644 --- a/backend/src/entities/user-actions/application/data-sctructures/create-user-action.ds.ts +++ b/backend/src/entities/user-actions/application/data-sctructures/create-user-action.ds.ts @@ -1,6 +1,6 @@ import { UserActionEnum } from '../../../../enums/index.js'; export class CreateUserActionDs { - message: UserActionEnum; - userId: string; + message: UserActionEnum; + userId: string; } diff --git a/backend/src/entities/user-actions/application/data-sctructures/created-user-action.ds.ts b/backend/src/entities/user-actions/application/data-sctructures/created-user-action.ds.ts index 22bd999d6..463a0edde 100644 --- a/backend/src/entities/user-actions/application/data-sctructures/created-user-action.ds.ts +++ b/backend/src/entities/user-actions/application/data-sctructures/created-user-action.ds.ts @@ -1,6 +1,6 @@ export class CreatedUserActionDs { - createdAt: Date; - id: string; - mail_sent: boolean; - message: string; + createdAt: Date; + id: string; + mail_sent: boolean; + message: string; } diff --git a/backend/src/entities/user-actions/dto/create-user-action.dto.ts b/backend/src/entities/user-actions/dto/create-user-action.dto.ts index d2916ef47..1859fdf21 100644 --- a/backend/src/entities/user-actions/dto/create-user-action.dto.ts +++ b/backend/src/entities/user-actions/dto/create-user-action.dto.ts @@ -1,10 +1,10 @@ import { ApiProperty } from '@nestjs/swagger'; -import { UserActionEnum } from '../../../enums/index.js'; import { IsEnum, IsNotEmpty } from 'class-validator'; +import { UserActionEnum } from '../../../enums/index.js'; export class CreateUserActionDto { - @ApiProperty({ enum: UserActionEnum }) - @IsNotEmpty() - @IsEnum(UserActionEnum) - message: UserActionEnum; + @ApiProperty({ enum: UserActionEnum }) + @IsNotEmpty() + @IsEnum(UserActionEnum) + message: UserActionEnum; } diff --git a/backend/src/entities/user-actions/repository/user-action-custom-repository-extension.ts b/backend/src/entities/user-actions/repository/user-action-custom-repository-extension.ts index 12788a507..0abcfe523 100644 --- a/backend/src/entities/user-actions/repository/user-action-custom-repository-extension.ts +++ b/backend/src/entities/user-actions/repository/user-action-custom-repository-extension.ts @@ -3,24 +3,24 @@ import { Constants } from '../../../helpers/constants/constants.js'; import { UserActionEntity } from '../user-action.entity.js'; export const userActionCustomRepositoryExtension = { - async saveNewOrUpdatedUserAction(userAction: UserActionEntity): Promise { - return await this.save(userAction); - }, + async saveNewOrUpdatedUserAction(userAction: UserActionEntity): Promise { + return await this.save(userAction); + }, - async findUserActionWithoutSentMail(userId: string): Promise { - const actionQb = this.createQueryBuilder('user_action') - .leftJoinAndSelect('user_action.user', 'user') - .andWhere('user.id = :user_id', { user_id: userId }) - .andWhere('user_action.mail_sent = :mail_sent', { mail_sent: false }); - return await actionQb.getOne(); - }, + async findUserActionWithoutSentMail(userId: string): Promise { + const actionQb = this.createQueryBuilder('user_action') + .leftJoinAndSelect('user_action.user', 'user') + .andWhere('user.id = :user_id', { user_id: userId }) + .andWhere('user_action.mail_sent = :mail_sent', { mail_sent: false }); + return await actionQb.getOne(); + }, - async findAllNonFinishedActionsTwoWeeksOld(): Promise> { - const notFinishedActionsQb = this.createQueryBuilder('user_action') - .leftJoinAndSelect('user_action.user', 'user') - .andWhere('user_action.createdAt <= :date_to', { date_to: Constants.ONE_WEEK_AGO() }) - .andWhere('user_action.mail_sent = :mail_sent', { mail_sent: false }) - .andWhere('user_action.message = :message', { message: UserActionEnum.CONNECTION_CREATION_NOT_FINISHED }); - return await notFinishedActionsQb.getMany(); - }, + async findAllNonFinishedActionsTwoWeeksOld(): Promise> { + const notFinishedActionsQb = this.createQueryBuilder('user_action') + .leftJoinAndSelect('user_action.user', 'user') + .andWhere('user_action.createdAt <= :date_to', { date_to: Constants.ONE_WEEK_AGO() }) + .andWhere('user_action.mail_sent = :mail_sent', { mail_sent: false }) + .andWhere('user_action.message = :message', { message: UserActionEnum.CONNECTION_CREATION_NOT_FINISHED }); + return await notFinishedActionsQb.getMany(); + }, }; diff --git a/backend/src/entities/user-actions/repository/user-action.repository.interface.ts b/backend/src/entities/user-actions/repository/user-action.repository.interface.ts index e7957c74e..0786f6830 100644 --- a/backend/src/entities/user-actions/repository/user-action.repository.interface.ts +++ b/backend/src/entities/user-actions/repository/user-action.repository.interface.ts @@ -1,9 +1,9 @@ import { UserActionEntity } from '../user-action.entity.js'; export interface IUserActionRepository { - saveNewOrUpdatedUserAction(userAction: UserActionEntity): Promise; + saveNewOrUpdatedUserAction(userAction: UserActionEntity): Promise; - findUserActionWithoutSentMail(userId: string): Promise; + findUserActionWithoutSentMail(userId: string): Promise; - findAllNonFinishedActionsTwoWeeksOld(): Promise>; + findAllNonFinishedActionsTwoWeeksOld(): Promise>; } diff --git a/backend/src/entities/user-actions/use-cases/check-users-actions-and-mailing-users.use.case.ts b/backend/src/entities/user-actions/use-cases/check-users-actions-and-mailing-users.use.case.ts index 12cbb56d1..4384736bf 100644 --- a/backend/src/entities/user-actions/use-cases/check-users-actions-and-mailing-users.use.case.ts +++ b/backend/src/entities/user-actions/use-cases/check-users-actions-and-mailing-users.use.case.ts @@ -1,130 +1,130 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; +import Sentry from '@sentry/minimal'; +import PQueue from 'p-queue'; import { Repository } from 'typeorm'; import { UserActionEnum } from '../../../enums/index.js'; -import { getUniqArrayStrings } from '../../../helpers/index.js'; import { Constants } from '../../../helpers/constants/constants.js'; +import { getUniqArrayStrings } from '../../../helpers/index.js'; import { UserEntity } from '../../user/user.entity.js'; import { UserActionEntity } from '../user-action.entity.js'; import { buildNewConnectionNotFinishedEmailSentAction } from '../utils/build-new-user-action-entity.js'; import { ICheckUsersActionsAndMailingUsers } from './use-cases-interfaces.js'; -import PQueue from 'p-queue'; -import Sentry from '@sentry/minimal'; @Injectable() export class CheckUsersActionsAndMailingUsersUseCase implements ICheckUsersActionsAndMailingUsers { - constructor( - @InjectRepository(UserActionEntity) - private readonly userActionRepository: Repository, - @InjectRepository(UserEntity) - private readonly userRepository: Repository, - ) {} - public async execute(): Promise> { - try { - const distinctUsers = await this.findDistinctUsersForProcessing(); - const batchSize = 10; - const emails: string[] = []; - const queue = new PQueue({ concurrency: 5 }); - for (let i = 0; i < distinctUsers.length; i += batchSize) { - const batch = distinctUsers.slice(i, i + batchSize); - for (const user of batch) { - try { - await queue.add(async () => { - await this.updateOrCreateActionForUser(user); - if (user.email) { - emails.push(user.email.toLowerCase()); - } - }); - } catch (error) { - console.error(`Error processing user ${user.id}: ${error.message}`); - Sentry.captureException(error); - } - } - await queue.onIdle(); - if (i + batchSize < distinctUsers.length) { - await new Promise((resolve) => setTimeout(resolve, 500)); - } - } - queue.clear(); - return getUniqArrayStrings(emails); - } catch (e) { - console.error('Error in CheckUsersActionsAndMailingUsersUseCase.execute():', e); - Sentry.captureException(e); - return []; - } - } + constructor( + @InjectRepository(UserActionEntity) + private readonly userActionRepository: Repository, + @InjectRepository(UserEntity) + private readonly userRepository: Repository, + ) {} + public async execute(): Promise> { + try { + const distinctUsers = await this.findDistinctUsersForProcessing(); + const batchSize = 10; + const emails: string[] = []; + const queue = new PQueue({ concurrency: 5 }); + for (let i = 0; i < distinctUsers.length; i += batchSize) { + const batch = distinctUsers.slice(i, i + batchSize); + for (const user of batch) { + try { + await queue.add(async () => { + await this.updateOrCreateActionForUser(user); + if (user.email) { + emails.push(user.email.toLowerCase()); + } + }); + } catch (error) { + console.error(`Error processing user ${user.id}: ${error.message}`); + Sentry.captureException(error); + } + } + await queue.onIdle(); + if (i + batchSize < distinctUsers.length) { + await new Promise((resolve) => setTimeout(resolve, 500)); + } + } + queue.clear(); + return getUniqArrayStrings(emails); + } catch (e) { + console.error('Error in CheckUsersActionsAndMailingUsersUseCase.execute():', e); + Sentry.captureException(e); + return []; + } + } - private async updateOrCreateActionForUser(u: { id: string; email: string }): Promise { - const userActionForUser = await this.findUserActionWithoutSentMail(u.id); - if (userActionForUser) { - if (!userActionForUser.mail_sent) { - userActionForUser.mail_sent = true; - await this.userActionRepository.save(userActionForUser); - } else { - return; - } - } - const foundUser = await this.userRepository.findOne({ where: { id: u.id } }); - const newUserActionEntity = buildNewConnectionNotFinishedEmailSentAction(foundUser); - await this.userActionRepository.save(newUserActionEntity); - } + private async updateOrCreateActionForUser(u: { id: string; email: string }): Promise { + const userActionForUser = await this.findUserActionWithoutSentMail(u.id); + if (userActionForUser) { + if (!userActionForUser.mail_sent) { + userActionForUser.mail_sent = true; + await this.userActionRepository.save(userActionForUser); + } else { + return; + } + } + const foundUser = await this.userRepository.findOne({ where: { id: u.id } }); + const newUserActionEntity = buildNewConnectionNotFinishedEmailSentAction(foundUser); + await this.userActionRepository.save(newUserActionEntity); + } - private async findUserActionWithoutSentMail(userId: string): Promise { - const actionQb = this.userActionRepository - .createQueryBuilder('user_action') - .leftJoinAndSelect('user_action.user', 'user') - .andWhere('user.id = :user_id', { user_id: userId }) - .andWhere('user_action.mail_sent = :mail_sent', { mail_sent: false }); - return await actionQb.getOne(); - } + private async findUserActionWithoutSentMail(userId: string): Promise { + const actionQb = this.userActionRepository + .createQueryBuilder('user_action') + .leftJoinAndSelect('user_action.user', 'user') + .andWhere('user.id = :user_id', { user_id: userId }) + .andWhere('user_action.mail_sent = :mail_sent', { mail_sent: false }); + return await actionQb.getOne(); + } - private async findDistinctUsersForProcessing(): Promise> { - try { - const nonFinishedActionsQuery = this.userActionRepository - .createQueryBuilder('user_action') - .select('DISTINCT user.id as id') - .addSelect('user.email as email') - .innerJoin('user_action.user', 'user') - .where('user.isDemoAccount = :isDemoAccount', { isDemoAccount: false }) - .andWhere('user_action.createdAt <= :date_to', { date_to: Constants.ONE_WEEK_AGO() }) - .andWhere('user_action.mail_sent = :mail_sent', { mail_sent: false }) - .andWhere('user_action.message = :message', { message: UserActionEnum.CONNECTION_CREATION_NOT_FINISHED }); + private async findDistinctUsersForProcessing(): Promise> { + try { + const nonFinishedActionsQuery = this.userActionRepository + .createQueryBuilder('user_action') + .select('DISTINCT user.id as id') + .addSelect('user.email as email') + .innerJoin('user_action.user', 'user') + .where('user.isDemoAccount = :isDemoAccount', { isDemoAccount: false }) + .andWhere('user_action.createdAt <= :date_to', { date_to: Constants.ONE_WEEK_AGO() }) + .andWhere('user_action.mail_sent = :mail_sent', { mail_sent: false }) + .andWhere('user_action.message = :message', { message: UserActionEnum.CONNECTION_CREATION_NOT_FINISHED }); - const uniqueUsersMap = new Map(); + const uniqueUsersMap = new Map(); - const nonFinishedUsers = await nonFinishedActionsQuery.getRawMany(); + const nonFinishedUsers = await nonFinishedActionsQuery.getRawMany(); - nonFinishedUsers.forEach((user) => { - if (!uniqueUsersMap.has(user.id)) { - uniqueUsersMap.set(user.id, { id: user.id, email: user.email }); - } - }); + nonFinishedUsers.forEach((user) => { + if (!uniqueUsersMap.has(user.id)) { + uniqueUsersMap.set(user.id, { id: user.id, email: user.email }); + } + }); - const usersWithoutLogsQuery = this.userRepository - .createQueryBuilder('user') - .select('DISTINCT user.id as id') - .addSelect('user.email as email') - .leftJoin('user.groups', 'group') - .leftJoin('group.connection', 'connection') - .leftJoin('connection.logs', 'tableLogs') - .leftJoin('user.user_action', 'user_action') - .where('user.isDemoAccount = :isDemoAccount', { isDemoAccount: false }) - .andWhere('(user_action.mail_sent = :mail_sent OR user_action.id is null)', { mail_sent: false }) - .andWhere('tableLogs.id is null') - .limit(500); + const usersWithoutLogsQuery = this.userRepository + .createQueryBuilder('user') + .select('DISTINCT user.id as id') + .addSelect('user.email as email') + .leftJoin('user.groups', 'group') + .leftJoin('group.connection', 'connection') + .leftJoin('connection.logs', 'tableLogs') + .leftJoin('user.user_action', 'user_action') + .where('user.isDemoAccount = :isDemoAccount', { isDemoAccount: false }) + .andWhere('(user_action.mail_sent = :mail_sent OR user_action.id is null)', { mail_sent: false }) + .andWhere('tableLogs.id is null') + .limit(500); - const usersWithoutLogs = await usersWithoutLogsQuery.getRawMany(); + const usersWithoutLogs = await usersWithoutLogsQuery.getRawMany(); - usersWithoutLogs.forEach((user) => { - if (!uniqueUsersMap.has(user.id)) { - uniqueUsersMap.set(user.id, { id: user.id, email: user.email }); - } - }); + usersWithoutLogs.forEach((user) => { + if (!uniqueUsersMap.has(user.id)) { + uniqueUsersMap.set(user.id, { id: user.id, email: user.email }); + } + }); - return Array.from(uniqueUsersMap.values()); - } catch (error) { - console.error('Error in findDistinctUsersForProcessing:', error); - Sentry.captureException(error); - return []; - } - } + return Array.from(uniqueUsersMap.values()); + } catch (error) { + console.error('Error in findDistinctUsersForProcessing:', error); + Sentry.captureException(error); + return []; + } + } } diff --git a/backend/src/entities/user-actions/use-cases/check-users-logs-and-update-actions.use.case.ts b/backend/src/entities/user-actions/use-cases/check-users-logs-and-update-actions.use.case.ts index f6f764cf0..4dcc42b8a 100644 --- a/backend/src/entities/user-actions/use-cases/check-users-logs-and-update-actions.use.case.ts +++ b/backend/src/entities/user-actions/use-cases/check-users-logs-and-update-actions.use.case.ts @@ -9,75 +9,75 @@ import { ICheckUsersLogsAndUpdateActionsUseCase } from './use-cases-interfaces.j @Injectable() export class CheckUsersLogsAndUpdateActionsUseCase implements ICheckUsersLogsAndUpdateActionsUseCase { - constructor( - @InjectRepository(UserActionEntity) - private readonly userActionRepository: Repository, - @InjectRepository(TableLogsEntity) - private readonly tableLogsRepository: Repository, - ) {} - public async execute(): Promise { - const uniqueUserIds: Array = await this.findDistinctUserIdsWithNonFinishedActions(); + constructor( + @InjectRepository(UserActionEntity) + private readonly userActionRepository: Repository, + @InjectRepository(TableLogsEntity) + private readonly tableLogsRepository: Repository, + ) {} + public async execute(): Promise { + const uniqueUserIds: Array = await this.findDistinctUserIdsWithNonFinishedActions(); - const batchSize = 3; - for (let i = 0; i < uniqueUserIds.length; i += batchSize) { - const batch = uniqueUserIds.slice(i, i + batchSize); - await Promise.allSettled( - batch.map(async (id: string) => { - await this.checkUserLogsAndUpdateAction(id); - }), - ); - } - } + const batchSize = 3; + for (let i = 0; i < uniqueUserIds.length; i += batchSize) { + const batch = uniqueUserIds.slice(i, i + batchSize); + await Promise.allSettled( + batch.map(async (id: string) => { + await this.checkUserLogsAndUpdateAction(id); + }), + ); + } + } - private async checkUserLogsAndUpdateAction(userId: string): Promise { - const hasSuccessfulTableReceivingLogs = await this.findSuccessfulTableReceivingUserLogs(userId); - if (!hasSuccessfulTableReceivingLogs) { - return; - } - const foundUserAction = await this.findNonFinishedConnectionCreationUserAction(userId); - if (!foundUserAction) { - return; - } - foundUserAction.message = UserActionEnum.CONNECTION_CREATION_FINISHED; - await this.userActionRepository.save(foundUserAction); - } + private async checkUserLogsAndUpdateAction(userId: string): Promise { + const hasSuccessfulTableReceivingLogs = await this.findSuccessfulTableReceivingUserLogs(userId); + if (!hasSuccessfulTableReceivingLogs) { + return; + } + const foundUserAction = await this.findNonFinishedConnectionCreationUserAction(userId); + if (!foundUserAction) { + return; + } + foundUserAction.message = UserActionEnum.CONNECTION_CREATION_FINISHED; + await this.userActionRepository.save(foundUserAction); + } - private async findDistinctUserIdsWithNonFinishedActions(): Promise> { - const result = await this.userActionRepository - .createQueryBuilder('user_action') - .select('DISTINCT user.id', 'userId') - .leftJoin('user_action.user', 'user') - .where('user_action.createdAt <= :date_to', { date_to: Constants.ONE_WEEK_AGO() }) - .andWhere('user_action.mail_sent = :mail_sent', { mail_sent: false }) - .andWhere('user_action.message = :message', { message: UserActionEnum.CONNECTION_CREATION_NOT_FINISHED }) - .getRawMany(); + private async findDistinctUserIdsWithNonFinishedActions(): Promise> { + const result = await this.userActionRepository + .createQueryBuilder('user_action') + .select('DISTINCT user.id', 'userId') + .leftJoin('user_action.user', 'user') + .where('user_action.createdAt <= :date_to', { date_to: Constants.ONE_WEEK_AGO() }) + .andWhere('user_action.mail_sent = :mail_sent', { mail_sent: false }) + .andWhere('user_action.message = :message', { message: UserActionEnum.CONNECTION_CREATION_NOT_FINISHED }) + .getRawMany(); - return result.map((item) => item.userId); - } + return result.map((item) => item.userId); + } - private async findSuccessfulTableReceivingUserLogs(userId: string): Promise { - const userLogsCount = await this.tableLogsRepository - .createQueryBuilder('tableLogs') - .leftJoin('tableLogs.connection_id', 'connection') - .leftJoin('connection.groups', 'group') - .leftJoin('group.users', 'user') - .where('user.id = :user_id', { user_id: userId }) - .andWhere('tableLogs.operationType = :operationType', { operationType: LogOperationTypeEnum.rowsReceived }) - .andWhere('tableLogs.operationStatusResult = :operationStatusResult', { - operationStatusResult: OperationResultStatusEnum.successfully, - }) - .select('1') - .limit(1) - .getRawOne(); - return !!userLogsCount; - } + private async findSuccessfulTableReceivingUserLogs(userId: string): Promise { + const userLogsCount = await this.tableLogsRepository + .createQueryBuilder('tableLogs') + .leftJoin('tableLogs.connection_id', 'connection') + .leftJoin('connection.groups', 'group') + .leftJoin('group.users', 'user') + .where('user.id = :user_id', { user_id: userId }) + .andWhere('tableLogs.operationType = :operationType', { operationType: LogOperationTypeEnum.rowsReceived }) + .andWhere('tableLogs.operationStatusResult = :operationStatusResult', { + operationStatusResult: OperationResultStatusEnum.successfully, + }) + .select('1') + .limit(1) + .getRawOne(); + return !!userLogsCount; + } - private async findNonFinishedConnectionCreationUserAction(userId: string): Promise { - const actionQb = this.userActionRepository - .createQueryBuilder('user_action') - .leftJoin('user_action.user', 'user') - .andWhere('user.id = :user_id', { user_id: userId }) - .andWhere('user_action.message = :message', { message: UserActionEnum.CONNECTION_CREATION_NOT_FINISHED }); - return await actionQb.getOne(); - } + private async findNonFinishedConnectionCreationUserAction(userId: string): Promise { + const actionQb = this.userActionRepository + .createQueryBuilder('user_action') + .leftJoin('user_action.user', 'user') + .andWhere('user.id = :user_id', { user_id: userId }) + .andWhere('user_action.message = :message', { message: UserActionEnum.CONNECTION_CREATION_NOT_FINISHED }); + return await actionQb.getOne(); + } } diff --git a/backend/src/entities/user-actions/use-cases/create-user-action.use.case.ts b/backend/src/entities/user-actions/use-cases/create-user-action.use.case.ts index 0d9c0fa36..d9c4ebbcc 100644 --- a/backend/src/entities/user-actions/use-cases/create-user-action.use.case.ts +++ b/backend/src/entities/user-actions/use-cases/create-user-action.use.case.ts @@ -11,35 +11,35 @@ import { ICreateUserAction } from './use-cases-interfaces.js'; @Injectable() export class CreateUserActionUseCase - extends AbstractUseCase - implements ICreateUserAction + extends AbstractUseCase + implements ICreateUserAction { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(actionData: CreateUserActionDs): Promise { - const { message, userId } = actionData; - const foundUser = await this._dbContext.userRepository.findOneUserWithUserAction(userId); - if (!foundUser) { - throw new HttpException( - { - message: Messages.USER_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - const userAction = foundUser.user_action; - if (userAction) { - userAction.message = message; - const updatedAction = await this._dbContext.userActionRepository.saveNewOrUpdatedUserAction(userAction); - return buildCreatedUserActionDs(updatedAction); - } - const newUserAction = buildNewUserActionEntity(actionData, foundUser); - const savedUserAction = await this._dbContext.userActionRepository.saveNewOrUpdatedUserAction(newUserAction); - return buildCreatedUserActionDs(savedUserAction); - } + protected async implementation(actionData: CreateUserActionDs): Promise { + const { message, userId } = actionData; + const foundUser = await this._dbContext.userRepository.findOneUserWithUserAction(userId); + if (!foundUser) { + throw new HttpException( + { + message: Messages.USER_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + const userAction = foundUser.user_action; + if (userAction) { + userAction.message = message; + const updatedAction = await this._dbContext.userActionRepository.saveNewOrUpdatedUserAction(userAction); + return buildCreatedUserActionDs(updatedAction); + } + const newUserAction = buildNewUserActionEntity(actionData, foundUser); + const savedUserAction = await this._dbContext.userActionRepository.saveNewOrUpdatedUserAction(newUserAction); + return buildCreatedUserActionDs(savedUserAction); + } } diff --git a/backend/src/entities/user-actions/use-cases/use-cases-interfaces.ts b/backend/src/entities/user-actions/use-cases/use-cases-interfaces.ts index adb170287..b97a2a505 100644 --- a/backend/src/entities/user-actions/use-cases/use-cases-interfaces.ts +++ b/backend/src/entities/user-actions/use-cases/use-cases-interfaces.ts @@ -3,13 +3,13 @@ import { CreateUserActionDs } from '../application/data-sctructures/create-user- import { CreatedUserActionDs } from '../application/data-sctructures/created-user-action.ds.js'; export interface ICreateUserAction { - execute(actionData: CreateUserActionDs, inTransaction: InTransactionEnum): Promise; + execute(actionData: CreateUserActionDs, inTransaction: InTransactionEnum): Promise; } export interface ICheckUsersLogsAndUpdateActionsUseCase { - execute(): Promise; + execute(): Promise; } export interface ICheckUsersActionsAndMailingUsers { - execute(): Promise>; + execute(): Promise>; } diff --git a/backend/src/entities/user-actions/user-action.controller.ts b/backend/src/entities/user-actions/user-action.controller.ts index 4f281b878..6c3e344df 100644 --- a/backend/src/entities/user-actions/user-action.controller.ts +++ b/backend/src/entities/user-actions/user-action.controller.ts @@ -1,14 +1,14 @@ import { Body, Controller, Inject, Injectable, Post, UseInterceptors } from '@nestjs/common'; +import { ApiBearerAuth, ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; import { UseCaseType } from '../../common/data-injection.tokens.js'; import { UserId } from '../../decorators/index.js'; +import { Timeout } from '../../decorators/timeout.decorator.js'; import { InTransactionEnum } from '../../enums/index.js'; import { SentryInterceptor } from '../../interceptors/index.js'; import { CreateUserActionDs } from './application/data-sctructures/create-user-action.ds.js'; +import { CreateUserActionDto } from './dto/create-user-action.dto.js'; import { ICreateUserAction } from './use-cases/use-cases-interfaces.js'; import { UserActionEntity } from './user-action.entity.js'; -import { ApiBearerAuth, ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; -import { CreateUserActionDto } from './dto/create-user-action.dto.js'; -import { Timeout } from '../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/user-actions/user-action.entity.ts b/backend/src/entities/user-actions/user-action.entity.ts index b7c1f401c..28320690f 100644 --- a/backend/src/entities/user-actions/user-action.entity.ts +++ b/backend/src/entities/user-actions/user-action.entity.ts @@ -3,19 +3,23 @@ import { UserEntity } from '../user/user.entity.js'; @Entity('user_action') export class UserActionEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ default: null }) - message: string; + @Column({ default: null }) + message: string; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - createdAt: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + createdAt: Date; - @Column({ default: false, type: 'boolean' }) - mail_sent: boolean; + @Column({ default: false, type: 'boolean' }) + mail_sent: boolean; - @OneToOne(() => UserEntity, (user) => user.user_action, { onDelete: 'CASCADE' }) - @JoinColumn() - user: Relation; + @OneToOne( + () => UserEntity, + (user) => user.user_action, + { onDelete: 'CASCADE' }, + ) + @JoinColumn() + user: Relation; } diff --git a/backend/src/entities/user-actions/user-action.module.ts b/backend/src/entities/user-actions/user-action.module.ts index 49d018ffa..421f7ddbb 100644 --- a/backend/src/entities/user-actions/user-action.module.ts +++ b/backend/src/entities/user-actions/user-action.module.ts @@ -10,25 +10,25 @@ import { UserActionController } from './user-action.controller.js'; import { UserActionEntity } from './user-action.entity.js'; @Module({ - imports: [TypeOrmModule.forFeature([UserActionEntity, UserEntity, LogOutEntity])], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.CREATE_USER_ACTION, - useClass: CreateUserActionUseCase, - }, - ], - controllers: [UserActionController], - exports: [], + imports: [TypeOrmModule.forFeature([UserActionEntity, UserEntity, LogOutEntity])], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.CREATE_USER_ACTION, + useClass: CreateUserActionUseCase, + }, + ], + controllers: [UserActionController], + exports: [], }) export class UserActionModule implements NestModule { - public configure(consumer: MiddlewareConsumer): void { - consumer.apply(AuthMiddleware).forRoutes({ - path: 'action', - method: RequestMethod.POST, - }); - } + public configure(consumer: MiddlewareConsumer): void { + consumer.apply(AuthMiddleware).forRoutes({ + path: 'action', + method: RequestMethod.POST, + }); + } } diff --git a/backend/src/entities/user-actions/utils/build-created-user-action-ds.ts b/backend/src/entities/user-actions/utils/build-created-user-action-ds.ts index 0b7241436..054f2024b 100644 --- a/backend/src/entities/user-actions/utils/build-created-user-action-ds.ts +++ b/backend/src/entities/user-actions/utils/build-created-user-action-ds.ts @@ -1,12 +1,12 @@ -import { UserActionEntity } from '../user-action.entity.js'; import { CreatedUserActionDs } from '../application/data-sctructures/created-user-action.ds.js'; +import { UserActionEntity } from '../user-action.entity.js'; export function buildCreatedUserActionDs(userAction: UserActionEntity): CreatedUserActionDs { - const { createdAt, message, id, mail_sent } = userAction; - return { - createdAt: createdAt, - id: id, - mail_sent: mail_sent, - message: message, - }; + const { createdAt, message, id, mail_sent } = userAction; + return { + createdAt: createdAt, + id: id, + mail_sent: mail_sent, + message: message, + }; } diff --git a/backend/src/entities/user-actions/utils/build-new-user-action-entity.ts b/backend/src/entities/user-actions/utils/build-new-user-action-entity.ts index a569662dc..a228cda67 100644 --- a/backend/src/entities/user-actions/utils/build-new-user-action-entity.ts +++ b/backend/src/entities/user-actions/utils/build-new-user-action-entity.ts @@ -1,20 +1,20 @@ -import { CreateUserActionDs } from '../application/data-sctructures/create-user-action.ds.js'; +import { UserActionEnum } from '../../../enums/index.js'; import { UserEntity } from '../../user/user.entity.js'; +import { CreateUserActionDs } from '../application/data-sctructures/create-user-action.ds.js'; import { UserActionEntity } from '../user-action.entity.js'; -import { UserActionEnum } from '../../../enums/index.js'; export function buildNewUserActionEntity(actionData: CreateUserActionDs, user: UserEntity): UserActionEntity { - const { message } = actionData; - const newUserAction = new UserActionEntity(); - newUserAction.user = user; - newUserAction.message = message; - return newUserAction; + const { message } = actionData; + const newUserAction = new UserActionEntity(); + newUserAction.user = user; + newUserAction.message = message; + return newUserAction; } export function buildNewConnectionNotFinishedEmailSentAction(user: UserEntity): UserActionEntity { - const newUserAction = new UserActionEntity(); - newUserAction.user = user; - newUserAction.message = UserActionEnum.CONNECTION_CREATION_NOT_FINISHED; - newUserAction.mail_sent = true; - return newUserAction; + const newUserAction = new UserActionEntity(); + newUserAction.user = user; + newUserAction.message = UserActionEnum.CONNECTION_CREATION_NOT_FINISHED; + newUserAction.mail_sent = true; + return newUserAction; } diff --git a/backend/src/entities/user-secret/application/data-structures/create-secret.ds.ts b/backend/src/entities/user-secret/application/data-structures/create-secret.ds.ts index a4fd71abe..e350e03a4 100644 --- a/backend/src/entities/user-secret/application/data-structures/create-secret.ds.ts +++ b/backend/src/entities/user-secret/application/data-structures/create-secret.ds.ts @@ -1,8 +1,8 @@ export class CreateSecretDS { - userId: string; - slug: string; - value: string; - expiresAt?: string; - masterEncryption?: boolean; - masterPassword?: string; + userId: string; + slug: string; + value: string; + expiresAt?: string; + masterEncryption?: boolean; + masterPassword?: string; } diff --git a/backend/src/entities/user-secret/application/data-structures/created-secret.ds.ts b/backend/src/entities/user-secret/application/data-structures/created-secret.ds.ts index b1b98bc88..1f194c072 100644 --- a/backend/src/entities/user-secret/application/data-structures/created-secret.ds.ts +++ b/backend/src/entities/user-secret/application/data-structures/created-secret.ds.ts @@ -1,10 +1,10 @@ export class CreatedSecretDS { - id: string; - slug: string; - companyId: string; - createdAt: Date; - updatedAt: Date; - lastAccessedAt?: Date; - expiresAt?: Date; - masterEncryption: boolean; + id: string; + slug: string; + companyId: string; + createdAt: Date; + updatedAt: Date; + lastAccessedAt?: Date; + expiresAt?: Date; + masterEncryption: boolean; } diff --git a/backend/src/entities/user-secret/application/data-structures/delete-secret.ds.ts b/backend/src/entities/user-secret/application/data-structures/delete-secret.ds.ts index 1de6f1b29..787f4b9f4 100644 --- a/backend/src/entities/user-secret/application/data-structures/delete-secret.ds.ts +++ b/backend/src/entities/user-secret/application/data-structures/delete-secret.ds.ts @@ -1,9 +1,9 @@ export class DeleteSecretDS { - userId: string; - slug: string; + userId: string; + slug: string; } export class DeletedSecretDS { - message: string; - deletedAt: Date; + message: string; + deletedAt: Date; } diff --git a/backend/src/entities/user-secret/application/data-structures/found-secret.ds.ts b/backend/src/entities/user-secret/application/data-structures/found-secret.ds.ts index fbd6320ce..b60557ad4 100644 --- a/backend/src/entities/user-secret/application/data-structures/found-secret.ds.ts +++ b/backend/src/entities/user-secret/application/data-structures/found-secret.ds.ts @@ -1,10 +1,10 @@ export class FoundSecretDS { - id: string; - slug: string; - companyId: string; - createdAt: Date; - updatedAt: Date; - lastAccessedAt?: Date; - expiresAt?: Date; - masterEncryption: boolean; + id: string; + slug: string; + companyId: string; + createdAt: Date; + updatedAt: Date; + lastAccessedAt?: Date; + expiresAt?: Date; + masterEncryption: boolean; } diff --git a/backend/src/entities/user-secret/application/data-structures/get-audit-log.ds.ts b/backend/src/entities/user-secret/application/data-structures/get-audit-log.ds.ts index e329a5c44..4b66779f2 100644 --- a/backend/src/entities/user-secret/application/data-structures/get-audit-log.ds.ts +++ b/backend/src/entities/user-secret/application/data-structures/get-audit-log.ds.ts @@ -2,27 +2,27 @@ import { SecretActionEnum } from '../../../secret-access-log/secret-access-log.e import { PaginationDs } from '../../../table/application/data-structures/pagination.ds.js'; export class GetAuditLogDS { - userId: string; - slug: string; - page: number; - limit: number; + userId: string; + slug: string; + page: number; + limit: number; } export class AuditLogEntryDS { - id: string; - action: SecretActionEnum; - user: { - id: string; - email: string; - }; - accessedAt: Date; - ipAddress?: string; - userAgent?: string; - success: boolean; - errorMessage?: string; + id: string; + action: SecretActionEnum; + user: { + id: string; + email: string; + }; + accessedAt: Date; + ipAddress?: string; + userAgent?: string; + success: boolean; + errorMessage?: string; } export class AuditLogListDS { - data: AuditLogEntryDS[]; - pagination: PaginationDs; + data: AuditLogEntryDS[]; + pagination: PaginationDs; } diff --git a/backend/src/entities/user-secret/application/data-structures/get-secret.ds.ts b/backend/src/entities/user-secret/application/data-structures/get-secret.ds.ts index 739d0d1c6..d13aedc95 100644 --- a/backend/src/entities/user-secret/application/data-structures/get-secret.ds.ts +++ b/backend/src/entities/user-secret/application/data-structures/get-secret.ds.ts @@ -1,4 +1,4 @@ export class GetSecretDS { - userId: string; - slug: string; + userId: string; + slug: string; } diff --git a/backend/src/entities/user-secret/application/data-structures/get-secrets.ds.ts b/backend/src/entities/user-secret/application/data-structures/get-secrets.ds.ts index 8b68bf4a4..f1371af11 100644 --- a/backend/src/entities/user-secret/application/data-structures/get-secrets.ds.ts +++ b/backend/src/entities/user-secret/application/data-structures/get-secrets.ds.ts @@ -1,24 +1,24 @@ import { PaginationDs } from '../../../table/application/data-structures/pagination.ds.js'; export class GetSecretsDS { - userId: string; - page: number; - limit: number; - search?: string; + userId: string; + page: number; + limit: number; + search?: string; } export class SecretListItemDS { - id: string; - slug: string; - companyId: string; - createdAt: Date; - updatedAt: Date; - lastAccessedAt?: Date; - expiresAt?: Date; - masterEncryption: boolean; + id: string; + slug: string; + companyId: string; + createdAt: Date; + updatedAt: Date; + lastAccessedAt?: Date; + expiresAt?: Date; + masterEncryption: boolean; } export class SecretsListDS { - data: SecretListItemDS[]; - pagination: PaginationDs; + data: SecretListItemDS[]; + pagination: PaginationDs; } diff --git a/backend/src/entities/user-secret/application/data-structures/update-secret.ds.ts b/backend/src/entities/user-secret/application/data-structures/update-secret.ds.ts index cefcd159b..62df0875f 100644 --- a/backend/src/entities/user-secret/application/data-structures/update-secret.ds.ts +++ b/backend/src/entities/user-secret/application/data-structures/update-secret.ds.ts @@ -1,18 +1,18 @@ export class UpdateSecretDS { - userId: string; - slug: string; - value?: string; - expiresAt?: string; - masterPassword?: string; + userId: string; + slug: string; + value?: string; + expiresAt?: string; + masterPassword?: string; } export class UpdatedSecretDS { - id: string; - slug: string; - companyId: string; - createdAt: Date; - updatedAt: Date; - lastAccessedAt?: Date; - expiresAt?: Date; - masterEncryption: boolean; + id: string; + slug: string; + companyId: string; + createdAt: Date; + updatedAt: Date; + lastAccessedAt?: Date; + expiresAt?: Date; + masterEncryption: boolean; } diff --git a/backend/src/entities/user-secret/application/dto/audit-log.dto.ts b/backend/src/entities/user-secret/application/dto/audit-log.dto.ts index 5585490b7..1c542b35d 100644 --- a/backend/src/entities/user-secret/application/dto/audit-log.dto.ts +++ b/backend/src/entities/user-secret/application/dto/audit-log.dto.ts @@ -3,93 +3,93 @@ import { SecretActionEnum } from '../../../secret-access-log/secret-access-log.e import { PaginationDs } from '../../../table/application/data-structures/pagination.ds.js'; export class AuditLogUserDto { - @ApiProperty({ - type: String, - description: 'User ID who performed the action', - example: '550e8400-e29b-41d4-a716-446655440002', - }) - id: string; + @ApiProperty({ + type: String, + description: 'User ID who performed the action', + example: '550e8400-e29b-41d4-a716-446655440002', + }) + id: string; - @ApiProperty({ - type: String, - description: 'Email of the user who performed the action', - example: 'user@example.com', - }) - email: string; + @ApiProperty({ + type: String, + description: 'Email of the user who performed the action', + example: 'user@example.com', + }) + email: string; } export class AuditLogEntryDto { - @ApiProperty({ - type: String, - description: 'Unique identifier of the audit log entry', - example: '550e8400-e29b-41d4-a716-446655440003', - }) - id: string; + @ApiProperty({ + type: String, + description: 'Unique identifier of the audit log entry', + example: '550e8400-e29b-41d4-a716-446655440003', + }) + id: string; - @ApiProperty({ - enum: SecretActionEnum, - enumName: 'SecretActionEnum', - description: 'Type of action performed on the secret', - example: SecretActionEnum.VIEW, - }) - action: SecretActionEnum; + @ApiProperty({ + enum: SecretActionEnum, + enumName: 'SecretActionEnum', + description: 'Type of action performed on the secret', + example: SecretActionEnum.VIEW, + }) + action: SecretActionEnum; - @ApiProperty({ - type: AuditLogUserDto, - description: 'User who performed the action', - }) - user: AuditLogUserDto; + @ApiProperty({ + type: AuditLogUserDto, + description: 'User who performed the action', + }) + user: AuditLogUserDto; - @ApiProperty({ - type: Date, - description: 'Date and time when the action was performed', - example: '2025-01-25T09:15:00.000Z', - }) - accessedAt: Date; + @ApiProperty({ + type: Date, + description: 'Date and time when the action was performed', + example: '2025-01-25T09:15:00.000Z', + }) + accessedAt: Date; - @ApiProperty({ - type: String, - required: false, - description: 'IP address from which the action was performed', - example: '192.168.1.100', - }) - ipAddress?: string; + @ApiProperty({ + type: String, + required: false, + description: 'IP address from which the action was performed', + example: '192.168.1.100', + }) + ipAddress?: string; - @ApiProperty({ - type: String, - required: false, - description: 'User agent string of the client', - example: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0', - }) - userAgent?: string; + @ApiProperty({ + type: String, + required: false, + description: 'User agent string of the client', + example: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0', + }) + userAgent?: string; - @ApiProperty({ - type: Boolean, - description: 'Whether the action was successful', - example: true, - }) - success: boolean; + @ApiProperty({ + type: Boolean, + description: 'Whether the action was successful', + example: true, + }) + success: boolean; - @ApiProperty({ - type: String, - required: false, - description: 'Error message if the action failed', - example: 'Invalid master password', - }) - errorMessage?: string; + @ApiProperty({ + type: String, + required: false, + description: 'Error message if the action failed', + example: 'Invalid master password', + }) + errorMessage?: string; } export class AuditLogResponseDto { - @ApiProperty({ - type: AuditLogEntryDto, - isArray: true, - description: 'List of audit log entries', - }) - data: AuditLogEntryDto[]; + @ApiProperty({ + type: AuditLogEntryDto, + isArray: true, + description: 'List of audit log entries', + }) + data: AuditLogEntryDto[]; - @ApiProperty({ - type: PaginationDs, - description: 'Pagination information', - }) - pagination: PaginationDs; + @ApiProperty({ + type: PaginationDs, + description: 'Pagination information', + }) + pagination: PaginationDs; } diff --git a/backend/src/entities/user-secret/application/dto/create-secret.dto.ts b/backend/src/entities/user-secret/application/dto/create-secret.dto.ts index d97c383f2..b9872fe1f 100644 --- a/backend/src/entities/user-secret/application/dto/create-secret.dto.ts +++ b/backend/src/entities/user-secret/application/dto/create-secret.dto.ts @@ -1,71 +1,81 @@ import { ApiProperty } from '@nestjs/swagger'; import { Transform } from 'class-transformer'; -import { IsBoolean, IsISO8601, IsNotEmpty, IsOptional, IsString, Matches, MaxLength, MinLength, ValidateIf } from 'class-validator'; +import { + IsBoolean, + IsISO8601, + IsNotEmpty, + IsOptional, + IsString, + Matches, + MaxLength, + MinLength, + ValidateIf, +} from 'class-validator'; export class CreateSecretDto { - @ApiProperty({ - type: String, - required: true, - description: 'Unique identifier for the secret within the company', - example: 'database-password', - minLength: 1, - maxLength: 255, - pattern: '^[a-zA-Z0-9_-]+$', - }) - @IsString() - @IsNotEmpty() - @MinLength(1) - @MaxLength(255) - @Matches(/^[a-zA-Z0-9_-]+$/, { - message: 'slug must contain only letters, numbers, hyphens, and underscores', - }) - @Transform(({ value }) => value.trim()) - slug: string; + @ApiProperty({ + type: String, + required: true, + description: 'Unique identifier for the secret within the company', + example: 'database-password', + minLength: 1, + maxLength: 255, + pattern: '^[a-zA-Z0-9_-]+$', + }) + @IsString() + @IsNotEmpty() + @MinLength(1) + @MaxLength(255) + @Matches(/^[a-zA-Z0-9_-]+$/, { + message: 'slug must contain only letters, numbers, hyphens, and underscores', + }) + @Transform(({ value }) => value.trim()) + slug: string; - @ApiProperty({ - type: String, - required: true, - description: 'The secret value to be stored (will be encrypted)', - example: 'my-secret-value-123', - minLength: 1, - maxLength: 10000, - }) - @IsString() - @IsNotEmpty() - @MinLength(1) - @MaxLength(10000) - value: string; + @ApiProperty({ + type: String, + required: true, + description: 'The secret value to be stored (will be encrypted)', + example: 'my-secret-value-123', + minLength: 1, + maxLength: 10000, + }) + @IsString() + @IsNotEmpty() + @MinLength(1) + @MaxLength(10000) + value: string; - @ApiProperty({ - type: String, - required: false, - description: 'ISO 8601 date when the secret should expire', - example: '2025-12-31T23:59:59.000Z', - }) - @IsOptional() - @IsISO8601() - expiresAt?: string; + @ApiProperty({ + type: String, + required: false, + description: 'ISO 8601 date when the secret should expire', + example: '2025-12-31T23:59:59.000Z', + }) + @IsOptional() + @IsISO8601() + expiresAt?: string; - @ApiProperty({ - type: Boolean, - required: false, - default: false, - description: 'Whether to encrypt the secret with a master password', - example: false, - }) - @IsBoolean() - @IsOptional() - masterEncryption?: boolean; + @ApiProperty({ + type: Boolean, + required: false, + default: false, + description: 'Whether to encrypt the secret with a master password', + example: false, + }) + @IsBoolean() + @IsOptional() + masterEncryption?: boolean; - @ApiProperty({ - type: String, - required: false, - description: 'Master password for additional encryption (required if masterEncryption is true)', - example: 'master-password-123', - minLength: 8, - }) - @IsString() - @MinLength(8) - @ValidateIf((o) => o.masterEncryption === true) - masterPassword?: string; + @ApiProperty({ + type: String, + required: false, + description: 'Master password for additional encryption (required if masterEncryption is true)', + example: 'master-password-123', + minLength: 8, + }) + @IsString() + @MinLength(8) + @ValidateIf((o) => o.masterEncryption === true) + masterPassword?: string; } diff --git a/backend/src/entities/user-secret/application/dto/delete-secret.dto.ts b/backend/src/entities/user-secret/application/dto/delete-secret.dto.ts index de98cd93d..ce6922659 100644 --- a/backend/src/entities/user-secret/application/dto/delete-secret.dto.ts +++ b/backend/src/entities/user-secret/application/dto/delete-secret.dto.ts @@ -1,17 +1,17 @@ import { ApiProperty } from '@nestjs/swagger'; export class DeleteSecretResponseDto { - @ApiProperty({ - type: String, - description: 'Confirmation message', - example: 'Secret deleted successfully', - }) - message: string; + @ApiProperty({ + type: String, + description: 'Confirmation message', + example: 'Secret deleted successfully', + }) + message: string; - @ApiProperty({ - type: Date, - description: 'Date and time when the secret was deleted', - example: '2025-01-25T10:30:00.000Z', - }) - deletedAt: Date; + @ApiProperty({ + type: Date, + description: 'Date and time when the secret was deleted', + example: '2025-01-25T10:30:00.000Z', + }) + deletedAt: Date; } diff --git a/backend/src/entities/user-secret/application/dto/found-secret.dto.ts b/backend/src/entities/user-secret/application/dto/found-secret.dto.ts index 5bd60eb59..3d4312a16 100644 --- a/backend/src/entities/user-secret/application/dto/found-secret.dto.ts +++ b/backend/src/entities/user-secret/application/dto/found-secret.dto.ts @@ -1,61 +1,61 @@ import { ApiProperty } from '@nestjs/swagger'; export class FoundSecretDto { - @ApiProperty({ - type: String, - description: 'Unique identifier of the secret', - example: '550e8400-e29b-41d4-a716-446655440000', - }) - id: string; - - @ApiProperty({ - type: String, - description: 'Unique slug identifier for the secret', - example: 'database-password', - }) - slug: string; - - @ApiProperty({ - type: String, - description: 'Company ID that owns this secret', - example: '550e8400-e29b-41d4-a716-446655440001', - }) - companyId: string; - - @ApiProperty({ - type: Date, - description: 'Date when the secret was created', - example: '2025-01-15T10:30:00.000Z', - }) - createdAt: Date; - - @ApiProperty({ - type: Date, - description: 'Date when the secret was last updated', - example: '2025-01-20T14:45:00.000Z', - }) - updatedAt: Date; - - @ApiProperty({ - type: Date, - required: false, - description: 'Date when the secret was last accessed', - example: '2025-01-25T09:15:00.000Z', - }) - lastAccessedAt?: Date; - - @ApiProperty({ - type: Date, - required: false, - description: 'Date when the secret expires (null if no expiration)', - example: '2025-12-31T23:59:59.000Z', - }) - expiresAt?: Date; - - @ApiProperty({ - type: Boolean, - description: 'Whether the secret requires a master password for decryption', - example: false, - }) - masterEncryption: boolean; + @ApiProperty({ + type: String, + description: 'Unique identifier of the secret', + example: '550e8400-e29b-41d4-a716-446655440000', + }) + id: string; + + @ApiProperty({ + type: String, + description: 'Unique slug identifier for the secret', + example: 'database-password', + }) + slug: string; + + @ApiProperty({ + type: String, + description: 'Company ID that owns this secret', + example: '550e8400-e29b-41d4-a716-446655440001', + }) + companyId: string; + + @ApiProperty({ + type: Date, + description: 'Date when the secret was created', + example: '2025-01-15T10:30:00.000Z', + }) + createdAt: Date; + + @ApiProperty({ + type: Date, + description: 'Date when the secret was last updated', + example: '2025-01-20T14:45:00.000Z', + }) + updatedAt: Date; + + @ApiProperty({ + type: Date, + required: false, + description: 'Date when the secret was last accessed', + example: '2025-01-25T09:15:00.000Z', + }) + lastAccessedAt?: Date; + + @ApiProperty({ + type: Date, + required: false, + description: 'Date when the secret expires (null if no expiration)', + example: '2025-12-31T23:59:59.000Z', + }) + expiresAt?: Date; + + @ApiProperty({ + type: Boolean, + description: 'Whether the secret requires a master password for decryption', + example: false, + }) + masterEncryption: boolean; } diff --git a/backend/src/entities/user-secret/application/dto/secret-list.dto.ts b/backend/src/entities/user-secret/application/dto/secret-list.dto.ts index a768c69f5..671fe3c0b 100644 --- a/backend/src/entities/user-secret/application/dto/secret-list.dto.ts +++ b/backend/src/entities/user-secret/application/dto/secret-list.dto.ts @@ -2,76 +2,76 @@ import { ApiProperty } from '@nestjs/swagger'; import { PaginationDs } from '../../../table/application/data-structures/pagination.ds.js'; export class SecretListItemDto { - @ApiProperty({ - type: String, - description: 'Unique identifier of the secret', - example: '550e8400-e29b-41d4-a716-446655440000', - }) - id: string; + @ApiProperty({ + type: String, + description: 'Unique identifier of the secret', + example: '550e8400-e29b-41d4-a716-446655440000', + }) + id: string; - @ApiProperty({ - type: String, - description: 'Unique slug identifier for the secret', - example: 'database-password', - }) - slug: string; + @ApiProperty({ + type: String, + description: 'Unique slug identifier for the secret', + example: 'database-password', + }) + slug: string; - @ApiProperty({ - type: String, - description: 'Company ID that owns this secret', - example: '550e8400-e29b-41d4-a716-446655440001', - }) - companyId: string; + @ApiProperty({ + type: String, + description: 'Company ID that owns this secret', + example: '550e8400-e29b-41d4-a716-446655440001', + }) + companyId: string; - @ApiProperty({ - type: Date, - description: 'Date when the secret was created', - example: '2025-01-15T10:30:00.000Z', - }) - createdAt: Date; + @ApiProperty({ + type: Date, + description: 'Date when the secret was created', + example: '2025-01-15T10:30:00.000Z', + }) + createdAt: Date; - @ApiProperty({ - type: Date, - description: 'Date when the secret was last updated', - example: '2025-01-20T14:45:00.000Z', - }) - updatedAt: Date; + @ApiProperty({ + type: Date, + description: 'Date when the secret was last updated', + example: '2025-01-20T14:45:00.000Z', + }) + updatedAt: Date; - @ApiProperty({ - type: Date, - required: false, - description: 'Date when the secret was last accessed', - example: '2025-01-25T09:15:00.000Z', - }) - lastAccessedAt?: Date; + @ApiProperty({ + type: Date, + required: false, + description: 'Date when the secret was last accessed', + example: '2025-01-25T09:15:00.000Z', + }) + lastAccessedAt?: Date; - @ApiProperty({ - type: Date, - required: false, - description: 'Date when the secret expires (null if no expiration)', - example: '2025-12-31T23:59:59.000Z', - }) - expiresAt?: Date; + @ApiProperty({ + type: Date, + required: false, + description: 'Date when the secret expires (null if no expiration)', + example: '2025-12-31T23:59:59.000Z', + }) + expiresAt?: Date; - @ApiProperty({ - type: Boolean, - description: 'Whether the secret requires a master password for decryption', - example: false, - }) - masterEncryption: boolean; + @ApiProperty({ + type: Boolean, + description: 'Whether the secret requires a master password for decryption', + example: false, + }) + masterEncryption: boolean; } export class SecretListResponseDto { - @ApiProperty({ - type: SecretListItemDto, - isArray: true, - description: 'List of secrets', - }) - data: SecretListItemDto[]; + @ApiProperty({ + type: SecretListItemDto, + isArray: true, + description: 'List of secrets', + }) + data: SecretListItemDto[]; - @ApiProperty({ - type: PaginationDs, - description: 'Pagination information', - }) - pagination: PaginationDs; + @ApiProperty({ + type: PaginationDs, + description: 'Pagination information', + }) + pagination: PaginationDs; } diff --git a/backend/src/entities/user-secret/application/dto/update-secret.dto.ts b/backend/src/entities/user-secret/application/dto/update-secret.dto.ts index 4037bc013..3ec8bfed2 100644 --- a/backend/src/entities/user-secret/application/dto/update-secret.dto.ts +++ b/backend/src/entities/user-secret/application/dto/update-secret.dto.ts @@ -2,27 +2,27 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsISO8601, IsNotEmpty, IsOptional, IsString, MaxLength, MinLength } from 'class-validator'; export class UpdateSecretDto { - @ApiProperty({ - type: String, - required: true, - description: 'The new secret value (will be encrypted)', - example: 'my-updated-secret-value-456', - minLength: 1, - maxLength: 10000, - }) - @IsString() - @IsNotEmpty() - @MinLength(1) - @MaxLength(10000) - value: string; + @ApiProperty({ + type: String, + required: true, + description: 'The new secret value (will be encrypted)', + example: 'my-updated-secret-value-456', + minLength: 1, + maxLength: 10000, + }) + @IsString() + @IsNotEmpty() + @MinLength(1) + @MaxLength(10000) + value: string; - @ApiProperty({ - type: String, - required: false, - description: 'ISO 8601 date when the secret should expire (null to remove expiration)', - example: '2025-12-31T23:59:59.000Z', - }) - @IsOptional() - @IsISO8601() - expiresAt?: string; + @ApiProperty({ + type: String, + required: false, + description: 'ISO 8601 date when the secret should expire (null to remove expiration)', + example: '2025-12-31T23:59:59.000Z', + }) + @IsOptional() + @IsISO8601() + expiresAt?: string; } diff --git a/backend/src/entities/user-secret/repository/user-secret-repository.extension.ts b/backend/src/entities/user-secret/repository/user-secret-repository.extension.ts index 9ac42f78c..e381da272 100644 --- a/backend/src/entities/user-secret/repository/user-secret-repository.extension.ts +++ b/backend/src/entities/user-secret/repository/user-secret-repository.extension.ts @@ -3,34 +3,34 @@ import { UserSecretEntity } from '../user-secret.entity.js'; import { IUserSecretRepository } from './user-secret-repository.interface.js'; export const userSecretRepositoryExtension: IUserSecretRepository = { - async findSecretBySlugAndCompanyId(slug: string, companyId: string): Promise { - return this.findOne({ - where: { - slug, - companyId, - }, - }); - }, + async findSecretBySlugAndCompanyId(slug: string, companyId: string): Promise { + return this.findOne({ + where: { + slug, + companyId, + }, + }); + }, - async findSecretsForCompany( - companyId: string, - options: { page: number; limit: number; search?: string }, - ): Promise<[UserSecretEntity[], number]> { - const where: FindOptionsWhere = { - companyId, - }; + async findSecretsForCompany( + companyId: string, + options: { page: number; limit: number; search?: string }, + ): Promise<[UserSecretEntity[], number]> { + const where: FindOptionsWhere = { + companyId, + }; - if (options.search) { - where.slug = Like(`%${options.search}%`); - } + if (options.search) { + where.slug = Like(`%${options.search}%`); + } - return this.findAndCount({ - where, - order: { - createdAt: 'DESC', - }, - skip: (options.page - 1) * options.limit, - take: options.limit, - }); - }, + return this.findAndCount({ + where, + order: { + createdAt: 'DESC', + }, + skip: (options.page - 1) * options.limit, + take: options.limit, + }); + }, }; diff --git a/backend/src/entities/user-secret/repository/user-secret-repository.interface.ts b/backend/src/entities/user-secret/repository/user-secret-repository.interface.ts index 8040435c7..865c2b099 100644 --- a/backend/src/entities/user-secret/repository/user-secret-repository.interface.ts +++ b/backend/src/entities/user-secret/repository/user-secret-repository.interface.ts @@ -2,14 +2,14 @@ import { Repository } from 'typeorm'; import { UserSecretEntity } from '../user-secret.entity.js'; export interface IUserSecretRepository { - findSecretBySlugAndCompanyId( - this: Repository, - slug: string, - companyId: string, - ): Promise; - findSecretsForCompany( - this: Repository, - companyId: string, - options: { page: number; limit: number; search?: string }, - ): Promise<[UserSecretEntity[], number]>; + findSecretBySlugAndCompanyId( + this: Repository, + slug: string, + companyId: string, + ): Promise; + findSecretsForCompany( + this: Repository, + companyId: string, + options: { page: number; limit: number; search?: string }, + ): Promise<[UserSecretEntity[], number]>; } diff --git a/backend/src/entities/user-secret/use-cases/create-secret.use.case.ts b/backend/src/entities/user-secret/use-cases/create-secret.use.case.ts index 793ea0513..96a441bca 100644 --- a/backend/src/entities/user-secret/use-cases/create-secret.use.case.ts +++ b/backend/src/entities/user-secret/use-cases/create-secret.use.case.ts @@ -1,65 +1,65 @@ import { ConflictException, Inject, Injectable, NotFoundException, Scope } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { BaseType } from '../../../common/data-injection.tokens.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; +import { BaseType } from '../../../common/data-injection.tokens.js'; +import { Messages } from '../../../exceptions/text/messages.js'; +import { Encryptor } from '../../../helpers/encryption/encryptor.js'; +import { SecretActionEnum } from '../../secret-access-log/secret-access-log.entity.js'; import { CreateSecretDS } from '../application/data-structures/create-secret.ds.js'; import { CreatedSecretDS } from '../application/data-structures/created-secret.ds.js'; -import { ICreateSecret } from './user-secret-use-cases.interface.js'; import { buildCreatedSecretDS } from '../utils/build-created-secret.ds.js'; -import { Encryptor } from '../../../helpers/encryption/encryptor.js'; -import { SecretActionEnum } from '../../secret-access-log/secret-access-log.entity.js'; -import { Messages } from '../../../exceptions/text/messages.js'; +import { ICreateSecret } from './user-secret-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class CreateSecretUseCase extends AbstractUseCase implements ICreateSecret { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: CreateSecretDS): Promise { - const { userId, slug, value, expiresAt, masterEncryption, masterPassword } = inputData; + protected async implementation(inputData: CreateSecretDS): Promise { + const { userId, slug, value, expiresAt, masterEncryption, masterPassword } = inputData; - const user = await this._dbContext.userRepository.findOne({ - where: { id: userId }, - relations: ['company'], - }); + const user = await this._dbContext.userRepository.findOne({ + where: { id: userId }, + relations: ['company'], + }); - if (!user || !user.company) { - throw new NotFoundException(Messages.USER_NOT_FOUND_OR_NOT_IN_COMPANY); - } + if (!user || !user.company) { + throw new NotFoundException(Messages.USER_NOT_FOUND_OR_NOT_IN_COMPANY); + } - const existing = await this._dbContext.userSecretRepository.findSecretBySlugAndCompanyId(slug, user.company.id); + const existing = await this._dbContext.userSecretRepository.findSecretBySlugAndCompanyId(slug, user.company.id); - if (existing) { - throw new ConflictException(Messages.SECRET_ALREADY_EXISTS); - } + if (existing) { + throw new ConflictException(Messages.SECRET_ALREADY_EXISTS); + } - let encryptedValue = value; + let encryptedValue = value; - if (masterEncryption && masterPassword) { - encryptedValue = Encryptor.encryptDataMasterPwd(encryptedValue, masterPassword); - } + if (masterEncryption && masterPassword) { + encryptedValue = Encryptor.encryptDataMasterPwd(encryptedValue, masterPassword); + } - encryptedValue = Encryptor.encryptData(encryptedValue); + encryptedValue = Encryptor.encryptData(encryptedValue); - const masterHash = masterPassword ? await Encryptor.hashUserPassword(masterPassword) : null; + const masterHash = masterPassword ? await Encryptor.hashUserPassword(masterPassword) : null; - const secret = this._dbContext.userSecretRepository.create({ - slug, - encryptedValue, - companyId: user.company.id, - expiresAt: expiresAt ? new Date(expiresAt) : null, - masterEncryption: masterEncryption || false, - masterHash, - }); + const secret = this._dbContext.userSecretRepository.create({ + slug, + encryptedValue, + companyId: user.company.id, + expiresAt: expiresAt ? new Date(expiresAt) : null, + masterEncryption: masterEncryption || false, + masterHash, + }); - const saved = await this._dbContext.userSecretRepository.save(secret); + const saved = await this._dbContext.userSecretRepository.save(secret); - await this._dbContext.secretAccessLogRepository.createAccessLog(saved.id, userId, SecretActionEnum.CREATE); + await this._dbContext.secretAccessLogRepository.createAccessLog(saved.id, userId, SecretActionEnum.CREATE); - return buildCreatedSecretDS(saved); - } + return buildCreatedSecretDS(saved); + } } diff --git a/backend/src/entities/user-secret/use-cases/delete-secret.use.case.ts b/backend/src/entities/user-secret/use-cases/delete-secret.use.case.ts index f740e31e4..d47519a28 100644 --- a/backend/src/entities/user-secret/use-cases/delete-secret.use.case.ts +++ b/backend/src/entities/user-secret/use-cases/delete-secret.use.case.ts @@ -1,46 +1,46 @@ import { Inject, Injectable, NotFoundException, Scope } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { BaseType } from '../../../common/data-injection.tokens.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; -import { DeleteSecretDS, DeletedSecretDS } from '../application/data-structures/delete-secret.ds.js'; -import { IDeleteSecret } from './user-secret-use-cases.interface.js'; -import { SecretActionEnum } from '../../secret-access-log/secret-access-log.entity.js'; +import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { SecretActionEnum } from '../../secret-access-log/secret-access-log.entity.js'; +import { DeletedSecretDS, DeleteSecretDS } from '../application/data-structures/delete-secret.ds.js'; +import { IDeleteSecret } from './user-secret-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class DeleteSecretUseCase extends AbstractUseCase implements IDeleteSecret { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: DeleteSecretDS): Promise { - const { userId, slug } = inputData; + protected async implementation(inputData: DeleteSecretDS): Promise { + const { userId, slug } = inputData; - const user = await this._dbContext.userRepository.findOne({ - where: { id: userId }, - relations: ['company'], - }); + const user = await this._dbContext.userRepository.findOne({ + where: { id: userId }, + relations: ['company'], + }); - if (!user || !user.company) { - throw new NotFoundException(Messages.USER_NOT_FOUND_OR_NOT_IN_COMPANY); - } + if (!user || !user.company) { + throw new NotFoundException(Messages.USER_NOT_FOUND_OR_NOT_IN_COMPANY); + } - const secret = await this._dbContext.userSecretRepository.findSecretBySlugAndCompanyId(slug, user.company.id); + const secret = await this._dbContext.userSecretRepository.findSecretBySlugAndCompanyId(slug, user.company.id); - if (!secret) { - throw new NotFoundException(Messages.SECRET_NOT_FOUND); - } + if (!secret) { + throw new NotFoundException(Messages.SECRET_NOT_FOUND); + } - await this._dbContext.secretAccessLogRepository.createAccessLog(secret.id, userId, SecretActionEnum.DELETE); + await this._dbContext.secretAccessLogRepository.createAccessLog(secret.id, userId, SecretActionEnum.DELETE); - await this._dbContext.userSecretRepository.remove(secret); + await this._dbContext.userSecretRepository.remove(secret); - return { - message: Messages.SECRET_DELETED_SUCCESSFULLY, - deletedAt: new Date(), - }; - } + return { + message: Messages.SECRET_DELETED_SUCCESSFULLY, + deletedAt: new Date(), + }; + } } diff --git a/backend/src/entities/user-secret/use-cases/get-secret-audit-log.use.case.ts b/backend/src/entities/user-secret/use-cases/get-secret-audit-log.use.case.ts index b3b2138e3..30a11217e 100644 --- a/backend/src/entities/user-secret/use-cases/get-secret-audit-log.use.case.ts +++ b/backend/src/entities/user-secret/use-cases/get-secret-audit-log.use.case.ts @@ -1,55 +1,55 @@ import { Inject, Injectable, NotFoundException, Scope } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { BaseType } from '../../../common/data-injection.tokens.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; +import { BaseType } from '../../../common/data-injection.tokens.js'; +import { Messages } from '../../../exceptions/text/messages.js'; import { AuditLogListDS, GetAuditLogDS } from '../application/data-structures/get-audit-log.ds.js'; -import { IGetSecretAuditLog } from './user-secret-use-cases.interface.js'; import { buildAuditLogEntryDS } from '../utils/build-audit-log-entry.ds.js'; -import { Messages } from '../../../exceptions/text/messages.js'; +import { IGetSecretAuditLog } from './user-secret-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class GetSecretAuditLogUseCase - extends AbstractUseCase - implements IGetSecretAuditLog + extends AbstractUseCase + implements IGetSecretAuditLog { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } - - protected async implementation(inputData: GetAuditLogDS): Promise { - const { userId, slug, page, limit } = inputData; - - const user = await this._dbContext.userRepository.findOne({ - where: { id: userId }, - relations: ['company'], - }); - - if (!user || !user.company) { - throw new NotFoundException(Messages.USER_NOT_FOUND_OR_NOT_IN_COMPANY); - } - - const secret = await this._dbContext.userSecretRepository.findSecretBySlugAndCompanyId(slug, user.company.id); - - if (!secret) { - throw new NotFoundException(Messages.SECRET_NOT_FOUND); - } - - const [logs, total] = await this._dbContext.secretAccessLogRepository.findLogsForSecret(secret.id, { - page, - limit, - }); - - return { - data: logs.map((log) => buildAuditLogEntryDS(log)), - pagination: { - total, - currentPage: page, - perPage: limit, - lastPage: Math.ceil(total / limit), - }, - }; - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } + + protected async implementation(inputData: GetAuditLogDS): Promise { + const { userId, slug, page, limit } = inputData; + + const user = await this._dbContext.userRepository.findOne({ + where: { id: userId }, + relations: ['company'], + }); + + if (!user || !user.company) { + throw new NotFoundException(Messages.USER_NOT_FOUND_OR_NOT_IN_COMPANY); + } + + const secret = await this._dbContext.userSecretRepository.findSecretBySlugAndCompanyId(slug, user.company.id); + + if (!secret) { + throw new NotFoundException(Messages.SECRET_NOT_FOUND); + } + + const [logs, total] = await this._dbContext.secretAccessLogRepository.findLogsForSecret(secret.id, { + page, + limit, + }); + + return { + data: logs.map((log) => buildAuditLogEntryDS(log)), + pagination: { + total, + currentPage: page, + perPage: limit, + lastPage: Math.ceil(total / limit), + }, + }; + } } diff --git a/backend/src/entities/user-secret/use-cases/get-secret-by-slug.use.case.ts b/backend/src/entities/user-secret/use-cases/get-secret-by-slug.use.case.ts index 1091a4b90..396452cb7 100644 --- a/backend/src/entities/user-secret/use-cases/get-secret-by-slug.use.case.ts +++ b/backend/src/entities/user-secret/use-cases/get-secret-by-slug.use.case.ts @@ -1,44 +1,44 @@ import { GoneException, Inject, Injectable, NotFoundException, Scope } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { BaseType } from '../../../common/data-injection.tokens.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; -import { GetSecretDS } from '../application/data-structures/get-secret.ds.js'; +import { BaseType } from '../../../common/data-injection.tokens.js'; +import { Messages } from '../../../exceptions/text/messages.js'; import { FoundSecretDS } from '../application/data-structures/found-secret.ds.js'; -import { IGetSecretBySlug } from './user-secret-use-cases.interface.js'; +import { GetSecretDS } from '../application/data-structures/get-secret.ds.js'; import { buildFoundSecretDS } from '../utils/build-found-secret.ds.js'; -import { Messages } from '../../../exceptions/text/messages.js'; +import { IGetSecretBySlug } from './user-secret-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class GetSecretBySlugUseCase extends AbstractUseCase implements IGetSecretBySlug { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: GetSecretDS): Promise { - const { userId, slug } = inputData; + protected async implementation(inputData: GetSecretDS): Promise { + const { userId, slug } = inputData; - const user = await this._dbContext.userRepository.findOne({ - where: { id: userId }, - relations: ['company'], - }); + const user = await this._dbContext.userRepository.findOne({ + where: { id: userId }, + relations: ['company'], + }); - if (!user || !user.company) { - throw new NotFoundException(Messages.USER_NOT_FOUND_OR_NOT_IN_COMPANY); - } + if (!user || !user.company) { + throw new NotFoundException(Messages.USER_NOT_FOUND_OR_NOT_IN_COMPANY); + } - const secret = await this._dbContext.userSecretRepository.findSecretBySlugAndCompanyId(slug, user.company.id); + const secret = await this._dbContext.userSecretRepository.findSecretBySlugAndCompanyId(slug, user.company.id); - if (!secret) { - throw new NotFoundException(Messages.SECRET_NOT_FOUND); - } + if (!secret) { + throw new NotFoundException(Messages.SECRET_NOT_FOUND); + } - if (secret.expiresAt && secret.expiresAt < new Date()) { - throw new GoneException(Messages.SECRET_EXPIRED); - } + if (secret.expiresAt && secret.expiresAt < new Date()) { + throw new GoneException(Messages.SECRET_EXPIRED); + } - return buildFoundSecretDS(secret); - } + return buildFoundSecretDS(secret); + } } diff --git a/backend/src/entities/user-secret/use-cases/get-secrets.use.case.ts b/backend/src/entities/user-secret/use-cases/get-secrets.use.case.ts index 947aa78f9..ef20d9ff6 100644 --- a/backend/src/entities/user-secret/use-cases/get-secrets.use.case.ts +++ b/backend/src/entities/user-secret/use-cases/get-secrets.use.case.ts @@ -1,47 +1,47 @@ import { Inject, Injectable, NotFoundException, Scope } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { BaseType } from '../../../common/data-injection.tokens.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; +import { BaseType } from '../../../common/data-injection.tokens.js'; +import { Messages } from '../../../exceptions/text/messages.js'; import { GetSecretsDS, SecretsListDS } from '../application/data-structures/get-secrets.ds.js'; -import { IGetSecrets } from './user-secret-use-cases.interface.js'; import { buildSecretListItemDS } from '../utils/build-secret-list-item.ds.js'; -import { Messages } from '../../../exceptions/text/messages.js'; +import { IGetSecrets } from './user-secret-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class GetSecretsUseCase extends AbstractUseCase implements IGetSecrets { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: GetSecretsDS): Promise { - const { userId, page, limit, search } = inputData; + protected async implementation(inputData: GetSecretsDS): Promise { + const { userId, page, limit, search } = inputData; - const user = await this._dbContext.userRepository.findOne({ - where: { id: userId }, - relations: ['company'], - }); + const user = await this._dbContext.userRepository.findOne({ + where: { id: userId }, + relations: ['company'], + }); - if (!user || !user.company) { - throw new NotFoundException(Messages.USER_NOT_FOUND_OR_NOT_IN_COMPANY); - } + if (!user || !user.company) { + throw new NotFoundException(Messages.USER_NOT_FOUND_OR_NOT_IN_COMPANY); + } - const [secrets, total] = await this._dbContext.userSecretRepository.findSecretsForCompany(user.company.id, { - page, - limit, - search, - }); + const [secrets, total] = await this._dbContext.userSecretRepository.findSecretsForCompany(user.company.id, { + page, + limit, + search, + }); - return { - data: secrets.map((secret) => buildSecretListItemDS(secret)), - pagination: { - total, - currentPage: page, - perPage: limit, - lastPage: Math.ceil(total / limit), - }, - }; - } + return { + data: secrets.map((secret) => buildSecretListItemDS(secret)), + pagination: { + total, + currentPage: page, + perPage: limit, + lastPage: Math.ceil(total / limit), + }, + }; + } } diff --git a/backend/src/entities/user-secret/use-cases/update-secret.use.case.ts b/backend/src/entities/user-secret/use-cases/update-secret.use.case.ts index b72ddb638..3c25b3517 100644 --- a/backend/src/entities/user-secret/use-cases/update-secret.use.case.ts +++ b/backend/src/entities/user-secret/use-cases/update-secret.use.case.ts @@ -1,82 +1,82 @@ import { ForbiddenException, GoneException, Inject, Injectable, NotFoundException, Scope } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { BaseType } from '../../../common/data-injection.tokens.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; -import { UpdateSecretDS, UpdatedSecretDS } from '../application/data-structures/update-secret.ds.js'; -import { IUpdateSecret } from './user-secret-use-cases.interface.js'; -import { buildUpdatedSecretDS } from '../utils/build-updated-secret.ds.js'; +import { BaseType } from '../../../common/data-injection.tokens.js'; +import { Messages } from '../../../exceptions/text/messages.js'; import { Encryptor } from '../../../helpers/encryption/encryptor.js'; import { SecretActionEnum } from '../../secret-access-log/secret-access-log.entity.js'; -import { Messages } from '../../../exceptions/text/messages.js'; +import { UpdatedSecretDS, UpdateSecretDS } from '../application/data-structures/update-secret.ds.js'; +import { buildUpdatedSecretDS } from '../utils/build-updated-secret.ds.js'; +import { IUpdateSecret } from './user-secret-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class UpdateSecretUseCase extends AbstractUseCase implements IUpdateSecret { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } - - protected async implementation(inputData: UpdateSecretDS): Promise { - const { userId, slug, value, expiresAt, masterPassword } = inputData; - - const user = await this._dbContext.userRepository.findOne({ - where: { id: userId }, - relations: ['company'], - }); - - if (!user || !user.company) { - throw new NotFoundException(Messages.USER_NOT_FOUND_OR_NOT_IN_COMPANY); - } - - const secret = await this._dbContext.userSecretRepository.findSecretBySlugAndCompanyId(slug, user.company.id); - - if (!secret) { - throw new NotFoundException(Messages.SECRET_NOT_FOUND); - } - - if (secret.expiresAt && secret.expiresAt < new Date()) { - throw new GoneException(Messages.SECRET_EXPIRED); - } - - if (secret.masterEncryption && !masterPassword) { - throw new ForbiddenException(Messages.SECRET_MASTER_PASSWORD_REQUIRED); - } - - if (secret.masterEncryption && masterPassword) { - const isValid = await Encryptor.verifyUserPassword(masterPassword, secret.masterHash); - if (!isValid) { - await this._dbContext.secretAccessLogRepository.createAccessLog( - secret.id, - userId, - SecretActionEnum.UPDATE, - false, - Messages.SECRET_MASTER_PASSWORD_INVALID, - ); - throw new ForbiddenException(Messages.SECRET_MASTER_PASSWORD_INVALID); - } - } - - if (value) { - let encryptedValue = value; - - if (secret.masterEncryption && masterPassword) { - encryptedValue = Encryptor.encryptDataMasterPwd(encryptedValue, masterPassword); - } - - encryptedValue = Encryptor.encryptData(encryptedValue); - secret.encryptedValue = encryptedValue; - } - - if (expiresAt !== undefined) { - secret.expiresAt = expiresAt ? new Date(expiresAt) : null; - } - - const updated = await this._dbContext.userSecretRepository.save(secret); - - await this._dbContext.secretAccessLogRepository.createAccessLog(secret.id, userId, SecretActionEnum.UPDATE); - - return buildUpdatedSecretDS(updated); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } + + protected async implementation(inputData: UpdateSecretDS): Promise { + const { userId, slug, value, expiresAt, masterPassword } = inputData; + + const user = await this._dbContext.userRepository.findOne({ + where: { id: userId }, + relations: ['company'], + }); + + if (!user || !user.company) { + throw new NotFoundException(Messages.USER_NOT_FOUND_OR_NOT_IN_COMPANY); + } + + const secret = await this._dbContext.userSecretRepository.findSecretBySlugAndCompanyId(slug, user.company.id); + + if (!secret) { + throw new NotFoundException(Messages.SECRET_NOT_FOUND); + } + + if (secret.expiresAt && secret.expiresAt < new Date()) { + throw new GoneException(Messages.SECRET_EXPIRED); + } + + if (secret.masterEncryption && !masterPassword) { + throw new ForbiddenException(Messages.SECRET_MASTER_PASSWORD_REQUIRED); + } + + if (secret.masterEncryption && masterPassword) { + const isValid = await Encryptor.verifyUserPassword(masterPassword, secret.masterHash); + if (!isValid) { + await this._dbContext.secretAccessLogRepository.createAccessLog( + secret.id, + userId, + SecretActionEnum.UPDATE, + false, + Messages.SECRET_MASTER_PASSWORD_INVALID, + ); + throw new ForbiddenException(Messages.SECRET_MASTER_PASSWORD_INVALID); + } + } + + if (value) { + let encryptedValue = value; + + if (secret.masterEncryption && masterPassword) { + encryptedValue = Encryptor.encryptDataMasterPwd(encryptedValue, masterPassword); + } + + encryptedValue = Encryptor.encryptData(encryptedValue); + secret.encryptedValue = encryptedValue; + } + + if (expiresAt !== undefined) { + secret.expiresAt = expiresAt ? new Date(expiresAt) : null; + } + + const updated = await this._dbContext.userSecretRepository.save(secret); + + await this._dbContext.secretAccessLogRepository.createAccessLog(secret.id, userId, SecretActionEnum.UPDATE); + + return buildUpdatedSecretDS(updated); + } } diff --git a/backend/src/entities/user-secret/use-cases/user-secret-use-cases.interface.ts b/backend/src/entities/user-secret/use-cases/user-secret-use-cases.interface.ts index ee1472aeb..dc9904fd2 100644 --- a/backend/src/entities/user-secret/use-cases/user-secret-use-cases.interface.ts +++ b/backend/src/entities/user-secret/use-cases/user-secret-use-cases.interface.ts @@ -1,7 +1,7 @@ import { InTransactionEnum } from '../../../enums/in-transaction.enum.js'; import { CreateSecretDS } from '../application/data-structures/create-secret.ds.js'; import { CreatedSecretDS } from '../application/data-structures/created-secret.ds.js'; -import { DeleteSecretDS, DeletedSecretDS } from '../application/data-structures/delete-secret.ds.js'; +import { DeletedSecretDS, DeleteSecretDS } from '../application/data-structures/delete-secret.ds.js'; import { FoundSecretDS } from '../application/data-structures/found-secret.ds.js'; import { AuditLogListDS, GetAuditLogDS } from '../application/data-structures/get-audit-log.ds.js'; import { GetSecretDS } from '../application/data-structures/get-secret.ds.js'; @@ -9,25 +9,25 @@ import { GetSecretsDS, SecretsListDS } from '../application/data-structures/get- import { UpdatedSecretDS, UpdateSecretDS } from '../application/data-structures/update-secret.ds.js'; export interface ICreateSecret { - execute(inputData: CreateSecretDS, inTransaction: InTransactionEnum): Promise; + execute(inputData: CreateSecretDS, inTransaction: InTransactionEnum): Promise; } export interface IGetSecrets { - execute(inputData: GetSecretsDS): Promise; + execute(inputData: GetSecretsDS): Promise; } export interface IGetSecretBySlug { - execute(inputData: GetSecretDS): Promise; + execute(inputData: GetSecretDS): Promise; } export interface IUpdateSecret { - execute(inputData: UpdateSecretDS, inTransaction: InTransactionEnum): Promise; + execute(inputData: UpdateSecretDS, inTransaction: InTransactionEnum): Promise; } export interface IDeleteSecret { - execute(inputData: DeleteSecretDS, inTransaction: InTransactionEnum): Promise; + execute(inputData: DeleteSecretDS, inTransaction: InTransactionEnum): Promise; } export interface IGetSecretAuditLog { - execute(inputData: GetAuditLogDS): Promise; + execute(inputData: GetAuditLogDS): Promise; } diff --git a/backend/src/entities/user-secret/user-secret.controller.ts b/backend/src/entities/user-secret/user-secret.controller.ts index 6b94623f4..48b69c230 100644 --- a/backend/src/entities/user-secret/user-secret.controller.ts +++ b/backend/src/entities/user-secret/user-secret.controller.ts @@ -15,18 +15,19 @@ import { UseInterceptors, } from '@nestjs/common'; import { ApiBearerAuth, ApiBody, ApiOperation, ApiParam, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger'; -import { UserId } from '../../decorators/user-id.decorator.js'; -import { MasterPassword } from '../../decorators/master-password.decorator.js'; -import { SentryInterceptor } from '../../interceptors/sentry.interceptor.js'; -import { CompanyUserGuard } from '../../guards/company-user.guard.js'; import { UseCaseType } from '../../common/data-injection.tokens.js'; +import { MasterPassword } from '../../decorators/master-password.decorator.js'; +import { Timeout } from '../../decorators/timeout.decorator.js'; +import { UserId } from '../../decorators/user-id.decorator.js'; import { InTransactionEnum } from '../../enums/in-transaction.enum.js'; +import { CompanyUserGuard } from '../../guards/company-user.guard.js'; +import { SentryInterceptor } from '../../interceptors/sentry.interceptor.js'; +import { AuditLogResponseDto } from './application/dto/audit-log.dto.js'; import { CreateSecretDto } from './application/dto/create-secret.dto.js'; -import { UpdateSecretDto } from './application/dto/update-secret.dto.js'; +import { DeleteSecretResponseDto } from './application/dto/delete-secret.dto.js'; import { FoundSecretDto } from './application/dto/found-secret.dto.js'; import { SecretListResponseDto } from './application/dto/secret-list.dto.js'; -import { AuditLogResponseDto } from './application/dto/audit-log.dto.js'; -import { DeleteSecretResponseDto } from './application/dto/delete-secret.dto.js'; +import { UpdateSecretDto } from './application/dto/update-secret.dto.js'; import { ICreateSecret, IDeleteSecret, @@ -35,12 +36,11 @@ import { IGetSecrets, IUpdateSecret, } from './use-cases/user-secret-use-cases.interface.js'; +import { buildAuditLogResponseDto } from './utils/build-audit-log.dto.js'; import { buildCreatedSecretDto } from './utils/build-created-secret.dto.js'; import { buildFoundSecretDto } from './utils/build-found-secret.dto.js'; -import { buildUpdatedSecretDto } from './utils/build-updated-secret.dto.js'; import { buildSecretListResponseDto } from './utils/build-secret-list.dto.js'; -import { buildAuditLogResponseDto } from './utils/build-audit-log.dto.js'; -import { Timeout } from '../../decorators/timeout.decorator.js'; +import { buildUpdatedSecretDto } from './utils/build-updated-secret.dto.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/user-secret/user-secret.entity.ts b/backend/src/entities/user-secret/user-secret.entity.ts index 1a9faaddf..3c9c68b2d 100644 --- a/backend/src/entities/user-secret/user-secret.entity.ts +++ b/backend/src/entities/user-secret/user-secret.entity.ts @@ -1,14 +1,14 @@ import { - Column, - CreateDateColumn, - Entity, - Index, - JoinColumn, - ManyToOne, - OneToMany, - PrimaryGeneratedColumn, - Relation, - UpdateDateColumn, + Column, + CreateDateColumn, + Entity, + Index, + JoinColumn, + ManyToOne, + OneToMany, + PrimaryGeneratedColumn, + Relation, + UpdateDateColumn, } from 'typeorm'; import { CompanyInfoEntity } from '../company-info/company-info.entity.js'; import { SecretAccessLogEntity } from '../secret-access-log/secret-access-log.entity.js'; @@ -16,41 +16,48 @@ import { SecretAccessLogEntity } from '../secret-access-log/secret-access-log.en @Entity('user_secrets') @Index(['companyId', 'slug'], { unique: true }) export class UserSecretEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @ManyToOne(() => CompanyInfoEntity, (company) => company.secrets, { onDelete: 'CASCADE' }) - @JoinColumn({ name: 'companyId' }) - company: Relation; + @ManyToOne( + () => CompanyInfoEntity, + (company) => company.secrets, + { onDelete: 'CASCADE' }, + ) + @JoinColumn({ name: 'companyId' }) + company: Relation; - @Column() - @Index() - companyId: string; + @Column() + @Index() + companyId: string; - @Column({ type: 'varchar', length: 255 }) - slug: string; + @Column({ type: 'varchar', length: 255 }) + slug: string; - @Column({ type: 'text' }) - encryptedValue: string; + @Column({ type: 'text' }) + encryptedValue: string; - @CreateDateColumn() - createdAt: Date; + @CreateDateColumn() + createdAt: Date; - @UpdateDateColumn() - updatedAt: Date; + @UpdateDateColumn() + updatedAt: Date; - @Column({ type: 'timestamp', nullable: true }) - lastAccessedAt: Date; + @Column({ type: 'timestamp', nullable: true }) + lastAccessedAt: Date; - @Column({ type: 'timestamp', nullable: true }) - expiresAt: Date; + @Column({ type: 'timestamp', nullable: true }) + expiresAt: Date; - @Column({ default: false }) - masterEncryption: boolean; + @Column({ default: false }) + masterEncryption: boolean; - @Column({ type: 'varchar', length: 4096, nullable: true }) - masterHash: string; + @Column({ type: 'varchar', length: 4096, nullable: true }) + masterHash: string; - @OneToMany(() => SecretAccessLogEntity, (log) => log.secret) - accessLogs: Relation[]; + @OneToMany( + () => SecretAccessLogEntity, + (log) => log.secret, + ) + accessLogs: Relation[]; } diff --git a/backend/src/entities/user-secret/user-secret.module.ts b/backend/src/entities/user-secret/user-secret.module.ts index aa5f1bb8d..1c95a4f29 100644 --- a/backend/src/entities/user-secret/user-secret.module.ts +++ b/backend/src/entities/user-secret/user-secret.module.ts @@ -1,81 +1,81 @@ import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { UserSecretEntity } from './user-secret.entity.js'; -import { SecretAccessLogEntity } from '../secret-access-log/secret-access-log.entity.js'; -import { UserEntity } from '../user/user.entity.js'; -import { UserSecretController } from './user-secret.controller.js'; import { AuthMiddleware } from '../../authorization/auth.middleware.js'; -import { LogOutEntity } from '../log-out/log-out.entity.js'; import { GlobalDatabaseContext } from '../../common/application/global-database-context.js'; import { BaseType, UseCaseType } from '../../common/data-injection.tokens.js'; +import { LogOutEntity } from '../log-out/log-out.entity.js'; +import { SecretAccessLogEntity } from '../secret-access-log/secret-access-log.entity.js'; +import { UserEntity } from '../user/user.entity.js'; import { CreateSecretUseCase } from './use-cases/create-secret.use.case.js'; -import { GetSecretsUseCase } from './use-cases/get-secrets.use.case.js'; -import { GetSecretBySlugUseCase } from './use-cases/get-secret-by-slug.use.case.js'; -import { UpdateSecretUseCase } from './use-cases/update-secret.use.case.js'; import { DeleteSecretUseCase } from './use-cases/delete-secret.use.case.js'; import { GetSecretAuditLogUseCase } from './use-cases/get-secret-audit-log.use.case.js'; +import { GetSecretBySlugUseCase } from './use-cases/get-secret-by-slug.use.case.js'; +import { GetSecretsUseCase } from './use-cases/get-secrets.use.case.js'; +import { UpdateSecretUseCase } from './use-cases/update-secret.use.case.js'; +import { UserSecretController } from './user-secret.controller.js'; +import { UserSecretEntity } from './user-secret.entity.js'; @Module({ - imports: [TypeOrmModule.forFeature([UserSecretEntity, SecretAccessLogEntity, UserEntity, LogOutEntity])], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.CREATE_SECRET, - useClass: CreateSecretUseCase, - }, - { - provide: UseCaseType.GET_SECRETS, - useClass: GetSecretsUseCase, - }, - { - provide: UseCaseType.GET_SECRET_BY_SLUG, - useClass: GetSecretBySlugUseCase, - }, - { - provide: UseCaseType.UPDATE_SECRET, - useClass: UpdateSecretUseCase, - }, - { - provide: UseCaseType.DELETE_SECRET, - useClass: DeleteSecretUseCase, - }, - { - provide: UseCaseType.GET_SECRET_AUDIT_LOG, - useClass: GetSecretAuditLogUseCase, - }, - ], - controllers: [UserSecretController], + imports: [TypeOrmModule.forFeature([UserSecretEntity, SecretAccessLogEntity, UserEntity, LogOutEntity])], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.CREATE_SECRET, + useClass: CreateSecretUseCase, + }, + { + provide: UseCaseType.GET_SECRETS, + useClass: GetSecretsUseCase, + }, + { + provide: UseCaseType.GET_SECRET_BY_SLUG, + useClass: GetSecretBySlugUseCase, + }, + { + provide: UseCaseType.UPDATE_SECRET, + useClass: UpdateSecretUseCase, + }, + { + provide: UseCaseType.DELETE_SECRET, + useClass: DeleteSecretUseCase, + }, + { + provide: UseCaseType.GET_SECRET_AUDIT_LOG, + useClass: GetSecretAuditLogUseCase, + }, + ], + controllers: [UserSecretController], }) export class UserSecretModule implements NestModule { - public configure(consumer: MiddlewareConsumer): void { - consumer.apply(AuthMiddleware).forRoutes( - { - path: '/secrets', - method: RequestMethod.POST, - }, - { - path: '/secrets', - method: RequestMethod.GET, - }, - { - path: '/secrets/:slug', - method: RequestMethod.GET, - }, - { - path: '/secrets/:slug', - method: RequestMethod.PUT, - }, - { - path: '/secrets/:slug', - method: RequestMethod.DELETE, - }, - { - path: '/secrets/:slug/audit-log', - method: RequestMethod.GET, - }, - ); - } + public configure(consumer: MiddlewareConsumer): void { + consumer.apply(AuthMiddleware).forRoutes( + { + path: '/secrets', + method: RequestMethod.POST, + }, + { + path: '/secrets', + method: RequestMethod.GET, + }, + { + path: '/secrets/:slug', + method: RequestMethod.GET, + }, + { + path: '/secrets/:slug', + method: RequestMethod.PUT, + }, + { + path: '/secrets/:slug', + method: RequestMethod.DELETE, + }, + { + path: '/secrets/:slug/audit-log', + method: RequestMethod.GET, + }, + ); + } } diff --git a/backend/src/entities/user-secret/utils/build-audit-log-entry.ds.ts b/backend/src/entities/user-secret/utils/build-audit-log-entry.ds.ts index 8112f8d27..a6b65f4e6 100644 --- a/backend/src/entities/user-secret/utils/build-audit-log-entry.ds.ts +++ b/backend/src/entities/user-secret/utils/build-audit-log-entry.ds.ts @@ -2,17 +2,17 @@ import { SecretAccessLogEntity } from '../../secret-access-log/secret-access-log import { AuditLogEntryDS } from '../application/data-structures/get-audit-log.ds.js'; export function buildAuditLogEntryDS(log: SecretAccessLogEntity): AuditLogEntryDS { - return { - id: log.id, - action: log.action, - user: { - id: log.user.id, - email: log.user.email, - }, - accessedAt: log.accessedAt, - ipAddress: log.ipAddress, - userAgent: log.userAgent, - success: log.success, - errorMessage: log.errorMessage, - }; + return { + id: log.id, + action: log.action, + user: { + id: log.user.id, + email: log.user.email, + }, + accessedAt: log.accessedAt, + ipAddress: log.ipAddress, + userAgent: log.userAgent, + success: log.success, + errorMessage: log.errorMessage, + }; } diff --git a/backend/src/entities/user-secret/utils/build-audit-log.dto.ts b/backend/src/entities/user-secret/utils/build-audit-log.dto.ts index 67a31561f..db2ece3d9 100644 --- a/backend/src/entities/user-secret/utils/build-audit-log.dto.ts +++ b/backend/src/entities/user-secret/utils/build-audit-log.dto.ts @@ -1,22 +1,22 @@ -import { AuditLogResponseDto, AuditLogEntryDto } from '../application/dto/audit-log.dto.js'; -import { AuditLogListDS, AuditLogEntryDS } from '../application/data-structures/get-audit-log.ds.js'; +import { AuditLogEntryDS, AuditLogListDS } from '../application/data-structures/get-audit-log.ds.js'; +import { AuditLogEntryDto, AuditLogResponseDto } from '../application/dto/audit-log.dto.js'; export function buildAuditLogEntryDto(ds: AuditLogEntryDS): AuditLogEntryDto { - return { - id: ds.id, - action: ds.action, - user: ds.user, - accessedAt: ds.accessedAt, - ipAddress: ds.ipAddress, - userAgent: ds.userAgent, - success: ds.success, - errorMessage: ds.errorMessage, - }; + return { + id: ds.id, + action: ds.action, + user: ds.user, + accessedAt: ds.accessedAt, + ipAddress: ds.ipAddress, + userAgent: ds.userAgent, + success: ds.success, + errorMessage: ds.errorMessage, + }; } export function buildAuditLogResponseDto(ds: AuditLogListDS): AuditLogResponseDto { - return { - data: ds.data.map(buildAuditLogEntryDto), - pagination: ds.pagination, - }; + return { + data: ds.data.map(buildAuditLogEntryDto), + pagination: ds.pagination, + }; } diff --git a/backend/src/entities/user-secret/utils/build-created-secret.ds.ts b/backend/src/entities/user-secret/utils/build-created-secret.ds.ts index 9a55c4d45..0ca5d292b 100644 --- a/backend/src/entities/user-secret/utils/build-created-secret.ds.ts +++ b/backend/src/entities/user-secret/utils/build-created-secret.ds.ts @@ -2,14 +2,14 @@ import { CreatedSecretDS } from '../application/data-structures/created-secret.d import { UserSecretEntity } from '../user-secret.entity.js'; export function buildCreatedSecretDS(secret: UserSecretEntity): CreatedSecretDS { - return { - id: secret.id, - slug: secret.slug, - companyId: secret.companyId, - createdAt: secret.createdAt, - updatedAt: secret.updatedAt, - lastAccessedAt: secret.lastAccessedAt, - expiresAt: secret.expiresAt, - masterEncryption: secret.masterEncryption, - }; + return { + id: secret.id, + slug: secret.slug, + companyId: secret.companyId, + createdAt: secret.createdAt, + updatedAt: secret.updatedAt, + lastAccessedAt: secret.lastAccessedAt, + expiresAt: secret.expiresAt, + masterEncryption: secret.masterEncryption, + }; } diff --git a/backend/src/entities/user-secret/utils/build-created-secret.dto.ts b/backend/src/entities/user-secret/utils/build-created-secret.dto.ts index 2e92ca020..c409c5ac6 100644 --- a/backend/src/entities/user-secret/utils/build-created-secret.dto.ts +++ b/backend/src/entities/user-secret/utils/build-created-secret.dto.ts @@ -1,15 +1,15 @@ -import { FoundSecretDto } from '../application/dto/found-secret.dto.js'; import { CreatedSecretDS } from '../application/data-structures/created-secret.ds.js'; +import { FoundSecretDto } from '../application/dto/found-secret.dto.js'; export function buildCreatedSecretDto(ds: CreatedSecretDS): FoundSecretDto { - return { - id: ds.id, - slug: ds.slug, - companyId: ds.companyId, - createdAt: ds.createdAt, - updatedAt: ds.updatedAt, - lastAccessedAt: ds.lastAccessedAt, - expiresAt: ds.expiresAt, - masterEncryption: ds.masterEncryption, - }; + return { + id: ds.id, + slug: ds.slug, + companyId: ds.companyId, + createdAt: ds.createdAt, + updatedAt: ds.updatedAt, + lastAccessedAt: ds.lastAccessedAt, + expiresAt: ds.expiresAt, + masterEncryption: ds.masterEncryption, + }; } diff --git a/backend/src/entities/user-secret/utils/build-found-secret.ds.ts b/backend/src/entities/user-secret/utils/build-found-secret.ds.ts index d51fc57cc..e7f56dca0 100644 --- a/backend/src/entities/user-secret/utils/build-found-secret.ds.ts +++ b/backend/src/entities/user-secret/utils/build-found-secret.ds.ts @@ -2,14 +2,14 @@ import { FoundSecretDS } from '../application/data-structures/found-secret.ds.js import { UserSecretEntity } from '../user-secret.entity.js'; export function buildFoundSecretDS(secret: UserSecretEntity): FoundSecretDS { - return { - id: secret.id, - slug: secret.slug, - companyId: secret.companyId, - createdAt: secret.createdAt, - updatedAt: secret.updatedAt, - lastAccessedAt: secret.lastAccessedAt, - expiresAt: secret.expiresAt, - masterEncryption: secret.masterEncryption, - }; + return { + id: secret.id, + slug: secret.slug, + companyId: secret.companyId, + createdAt: secret.createdAt, + updatedAt: secret.updatedAt, + lastAccessedAt: secret.lastAccessedAt, + expiresAt: secret.expiresAt, + masterEncryption: secret.masterEncryption, + }; } diff --git a/backend/src/entities/user-secret/utils/build-found-secret.dto.ts b/backend/src/entities/user-secret/utils/build-found-secret.dto.ts index eb542c247..54ce2a3bc 100644 --- a/backend/src/entities/user-secret/utils/build-found-secret.dto.ts +++ b/backend/src/entities/user-secret/utils/build-found-secret.dto.ts @@ -1,15 +1,15 @@ -import { FoundSecretDto } from '../application/dto/found-secret.dto.js'; import { FoundSecretDS } from '../application/data-structures/found-secret.ds.js'; +import { FoundSecretDto } from '../application/dto/found-secret.dto.js'; export function buildFoundSecretDto(ds: FoundSecretDS): FoundSecretDto { - return { - id: ds.id, - slug: ds.slug, - companyId: ds.companyId, - createdAt: ds.createdAt, - updatedAt: ds.updatedAt, - lastAccessedAt: ds.lastAccessedAt, - expiresAt: ds.expiresAt, - masterEncryption: ds.masterEncryption, - }; + return { + id: ds.id, + slug: ds.slug, + companyId: ds.companyId, + createdAt: ds.createdAt, + updatedAt: ds.updatedAt, + lastAccessedAt: ds.lastAccessedAt, + expiresAt: ds.expiresAt, + masterEncryption: ds.masterEncryption, + }; } diff --git a/backend/src/entities/user-secret/utils/build-secret-list-item.ds.ts b/backend/src/entities/user-secret/utils/build-secret-list-item.ds.ts index 37b63eb9a..6497ac5dd 100644 --- a/backend/src/entities/user-secret/utils/build-secret-list-item.ds.ts +++ b/backend/src/entities/user-secret/utils/build-secret-list-item.ds.ts @@ -2,14 +2,14 @@ import { SecretListItemDS } from '../application/data-structures/get-secrets.ds. import { UserSecretEntity } from '../user-secret.entity.js'; export function buildSecretListItemDS(secret: UserSecretEntity): SecretListItemDS { - return { - id: secret.id, - slug: secret.slug, - companyId: secret.companyId, - createdAt: secret.createdAt, - updatedAt: secret.updatedAt, - lastAccessedAt: secret.lastAccessedAt, - expiresAt: secret.expiresAt, - masterEncryption: secret.masterEncryption, - }; + return { + id: secret.id, + slug: secret.slug, + companyId: secret.companyId, + createdAt: secret.createdAt, + updatedAt: secret.updatedAt, + lastAccessedAt: secret.lastAccessedAt, + expiresAt: secret.expiresAt, + masterEncryption: secret.masterEncryption, + }; } diff --git a/backend/src/entities/user-secret/utils/build-secret-list.dto.ts b/backend/src/entities/user-secret/utils/build-secret-list.dto.ts index add45f480..6f11459da 100644 --- a/backend/src/entities/user-secret/utils/build-secret-list.dto.ts +++ b/backend/src/entities/user-secret/utils/build-secret-list.dto.ts @@ -1,22 +1,22 @@ -import { SecretListResponseDto, SecretListItemDto } from '../application/dto/secret-list.dto.js'; -import { SecretsListDS, SecretListItemDS } from '../application/data-structures/get-secrets.ds.js'; +import { SecretListItemDS, SecretsListDS } from '../application/data-structures/get-secrets.ds.js'; +import { SecretListItemDto, SecretListResponseDto } from '../application/dto/secret-list.dto.js'; export function buildSecretListItemDto(ds: SecretListItemDS): SecretListItemDto { - return { - id: ds.id, - slug: ds.slug, - companyId: ds.companyId, - createdAt: ds.createdAt, - updatedAt: ds.updatedAt, - lastAccessedAt: ds.lastAccessedAt, - expiresAt: ds.expiresAt, - masterEncryption: ds.masterEncryption, - }; + return { + id: ds.id, + slug: ds.slug, + companyId: ds.companyId, + createdAt: ds.createdAt, + updatedAt: ds.updatedAt, + lastAccessedAt: ds.lastAccessedAt, + expiresAt: ds.expiresAt, + masterEncryption: ds.masterEncryption, + }; } export function buildSecretListResponseDto(ds: SecretsListDS): SecretListResponseDto { - return { - data: ds.data.map(buildSecretListItemDto), - pagination: ds.pagination, - }; + return { + data: ds.data.map(buildSecretListItemDto), + pagination: ds.pagination, + }; } diff --git a/backend/src/entities/user-secret/utils/build-updated-secret.ds.ts b/backend/src/entities/user-secret/utils/build-updated-secret.ds.ts index d42b19321..43499f8e1 100644 --- a/backend/src/entities/user-secret/utils/build-updated-secret.ds.ts +++ b/backend/src/entities/user-secret/utils/build-updated-secret.ds.ts @@ -2,14 +2,14 @@ import { UpdatedSecretDS } from '../application/data-structures/update-secret.ds import { UserSecretEntity } from '../user-secret.entity.js'; export function buildUpdatedSecretDS(secret: UserSecretEntity): UpdatedSecretDS { - return { - id: secret.id, - slug: secret.slug, - companyId: secret.companyId, - createdAt: secret.createdAt, - updatedAt: secret.updatedAt, - lastAccessedAt: secret.lastAccessedAt, - expiresAt: secret.expiresAt, - masterEncryption: secret.masterEncryption, - }; + return { + id: secret.id, + slug: secret.slug, + companyId: secret.companyId, + createdAt: secret.createdAt, + updatedAt: secret.updatedAt, + lastAccessedAt: secret.lastAccessedAt, + expiresAt: secret.expiresAt, + masterEncryption: secret.masterEncryption, + }; } diff --git a/backend/src/entities/user-secret/utils/build-updated-secret.dto.ts b/backend/src/entities/user-secret/utils/build-updated-secret.dto.ts index 6826ca3ed..78859f27b 100644 --- a/backend/src/entities/user-secret/utils/build-updated-secret.dto.ts +++ b/backend/src/entities/user-secret/utils/build-updated-secret.dto.ts @@ -1,15 +1,15 @@ -import { FoundSecretDto } from '../application/dto/found-secret.dto.js'; import { UpdatedSecretDS } from '../application/data-structures/update-secret.ds.js'; +import { FoundSecretDto } from '../application/dto/found-secret.dto.js'; export function buildUpdatedSecretDto(ds: UpdatedSecretDS): FoundSecretDto { - return { - id: ds.id, - slug: ds.slug, - companyId: ds.companyId, - createdAt: ds.createdAt, - updatedAt: ds.updatedAt, - lastAccessedAt: ds.lastAccessedAt, - expiresAt: ds.expiresAt, - masterEncryption: ds.masterEncryption, - }; + return { + id: ds.id, + slug: ds.slug, + companyId: ds.companyId, + createdAt: ds.createdAt, + updatedAt: ds.updatedAt, + lastAccessedAt: ds.lastAccessedAt, + expiresAt: ds.expiresAt, + masterEncryption: ds.masterEncryption, + }; } diff --git a/backend/src/entities/user-sign-in-audit/dto/create-sign-in-audit-record.ds.ts b/backend/src/entities/user-sign-in-audit/dto/create-sign-in-audit-record.ds.ts index f0cd956e5..25013458d 100644 --- a/backend/src/entities/user-sign-in-audit/dto/create-sign-in-audit-record.ds.ts +++ b/backend/src/entities/user-sign-in-audit/dto/create-sign-in-audit-record.ds.ts @@ -2,11 +2,11 @@ import { SignInMethodEnum } from '../enums/sign-in-method.enum.js'; import { SignInStatusEnum } from '../enums/sign-in-status.enum.js'; export class CreateSignInAuditRecordDs { - email: string; - userId?: string; - status: SignInStatusEnum; - signInMethod: SignInMethodEnum; - ipAddress?: string; - userAgent?: string; - failureReason?: string; + email: string; + userId?: string; + status: SignInStatusEnum; + signInMethod: SignInMethodEnum; + ipAddress?: string; + userAgent?: string; + failureReason?: string; } diff --git a/backend/src/entities/user-sign-in-audit/dto/find-sign-in-audit-logs.ds.ts b/backend/src/entities/user-sign-in-audit/dto/find-sign-in-audit-logs.ds.ts index 78724f006..56954c01d 100644 --- a/backend/src/entities/user-sign-in-audit/dto/find-sign-in-audit-logs.ds.ts +++ b/backend/src/entities/user-sign-in-audit/dto/find-sign-in-audit-logs.ds.ts @@ -2,16 +2,16 @@ import { SignInMethodEnum } from '../enums/sign-in-method.enum.js'; import { SignInStatusEnum } from '../enums/sign-in-status.enum.js'; export class FindSignInAuditLogsDs { - userId: string; - companyId: string; - query: { - order?: string; - page?: number; - perPage?: number; - dateFrom?: string; - dateTo?: string; - email?: string; - status?: SignInStatusEnum; - signInMethod?: SignInMethodEnum; - }; + userId: string; + companyId: string; + query: { + order?: string; + page?: number; + perPage?: number; + dateFrom?: string; + dateTo?: string; + email?: string; + status?: SignInStatusEnum; + signInMethod?: SignInMethodEnum; + }; } diff --git a/backend/src/entities/user-sign-in-audit/dto/found-sign-in-audit-logs.ds.ts b/backend/src/entities/user-sign-in-audit/dto/found-sign-in-audit-logs.ds.ts index 0e5e284aa..cee52b7a8 100644 --- a/backend/src/entities/user-sign-in-audit/dto/found-sign-in-audit-logs.ds.ts +++ b/backend/src/entities/user-sign-in-audit/dto/found-sign-in-audit-logs.ds.ts @@ -3,9 +3,9 @@ import { PaginationDs } from '../../table/application/data-structures/pagination import { FoundSignInAuditRecordDs } from './found-sign-in-audit-record.ds.js'; export class FoundSignInAuditLogsDs { - @ApiProperty({ isArray: true, type: FoundSignInAuditRecordDs }) - logs: Array; + @ApiProperty({ isArray: true, type: FoundSignInAuditRecordDs }) + logs: Array; - @ApiProperty({ type: PaginationDs }) - pagination: PaginationDs; + @ApiProperty({ type: PaginationDs }) + pagination: PaginationDs; } diff --git a/backend/src/entities/user-sign-in-audit/dto/found-sign-in-audit-record.ds.ts b/backend/src/entities/user-sign-in-audit/dto/found-sign-in-audit-record.ds.ts index ed23b64c4..276c80fb7 100644 --- a/backend/src/entities/user-sign-in-audit/dto/found-sign-in-audit-record.ds.ts +++ b/backend/src/entities/user-sign-in-audit/dto/found-sign-in-audit-record.ds.ts @@ -3,30 +3,30 @@ import { SignInMethodEnum } from '../enums/sign-in-method.enum.js'; import { SignInStatusEnum } from '../enums/sign-in-status.enum.js'; export class FoundSignInAuditRecordDs { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - email: string; + @ApiProperty() + email: string; - @ApiProperty({ enum: SignInStatusEnum }) - status: SignInStatusEnum; + @ApiProperty({ enum: SignInStatusEnum }) + status: SignInStatusEnum; - @ApiProperty({ enum: SignInMethodEnum }) - signInMethod: SignInMethodEnum; + @ApiProperty({ enum: SignInMethodEnum }) + signInMethod: SignInMethodEnum; - @ApiProperty() - ipAddress: string; + @ApiProperty() + ipAddress: string; - @ApiProperty() - userAgent: string; + @ApiProperty() + userAgent: string; - @ApiProperty() - failureReason: string; + @ApiProperty() + failureReason: string; - @ApiProperty() - createdAt: Date; + @ApiProperty() + createdAt: Date; - @ApiProperty() - userId: string; + @ApiProperty() + userId: string; } diff --git a/backend/src/entities/user-sign-in-audit/dto/index.ts b/backend/src/entities/user-sign-in-audit/dto/index.ts index c9dc7181f..fdb0ec7ce 100644 --- a/backend/src/entities/user-sign-in-audit/dto/index.ts +++ b/backend/src/entities/user-sign-in-audit/dto/index.ts @@ -1,4 +1,4 @@ export * from './create-sign-in-audit-record.ds.js'; -export * from './found-sign-in-audit-record.ds.js'; -export * from './found-sign-in-audit-logs.ds.js'; export * from './find-sign-in-audit-logs.ds.js'; +export * from './found-sign-in-audit-logs.ds.js'; +export * from './found-sign-in-audit-record.ds.js'; diff --git a/backend/src/entities/user-sign-in-audit/enums/index.ts b/backend/src/entities/user-sign-in-audit/enums/index.ts index 0c7d1e140..5a6b92461 100644 --- a/backend/src/entities/user-sign-in-audit/enums/index.ts +++ b/backend/src/entities/user-sign-in-audit/enums/index.ts @@ -1,2 +1,2 @@ -export * from './sign-in-status.enum.js'; export * from './sign-in-method.enum.js'; +export * from './sign-in-status.enum.js'; diff --git a/backend/src/entities/user-sign-in-audit/enums/sign-in-method.enum.ts b/backend/src/entities/user-sign-in-audit/enums/sign-in-method.enum.ts index ee5c69f72..bdf33a703 100644 --- a/backend/src/entities/user-sign-in-audit/enums/sign-in-method.enum.ts +++ b/backend/src/entities/user-sign-in-audit/enums/sign-in-method.enum.ts @@ -1,7 +1,7 @@ export enum SignInMethodEnum { - EMAIL = 'email', - GOOGLE = 'google', - GITHUB = 'github', - SAML = 'saml', - OTP = 'otp', + EMAIL = 'email', + GOOGLE = 'google', + GITHUB = 'github', + SAML = 'saml', + OTP = 'otp', } diff --git a/backend/src/entities/user-sign-in-audit/enums/sign-in-status.enum.ts b/backend/src/entities/user-sign-in-audit/enums/sign-in-status.enum.ts index d3ccabbf3..f9e12b9a9 100644 --- a/backend/src/entities/user-sign-in-audit/enums/sign-in-status.enum.ts +++ b/backend/src/entities/user-sign-in-audit/enums/sign-in-status.enum.ts @@ -1,5 +1,5 @@ export enum SignInStatusEnum { - SUCCESS = 'success', - FAILED = 'failed', - BLOCKED = 'blocked', + SUCCESS = 'success', + FAILED = 'failed', + BLOCKED = 'blocked', } diff --git a/backend/src/entities/user-sign-in-audit/repository/sign-in-audit-custom-repository-extension.ts b/backend/src/entities/user-sign-in-audit/repository/sign-in-audit-custom-repository-extension.ts index 1c3638e19..118d91a07 100644 --- a/backend/src/entities/user-sign-in-audit/repository/sign-in-audit-custom-repository-extension.ts +++ b/backend/src/entities/user-sign-in-audit/repository/sign-in-audit-custom-repository-extension.ts @@ -2,127 +2,127 @@ import { UserEntity } from '../../user/user.entity.js'; import { CreateSignInAuditRecordDs } from '../dto/create-sign-in-audit-record.ds.js'; import { SignInAuditEntity } from '../sign-in-audit.entity.js'; import { - IFindSignInAuditLogsOptions, - IFoundSignInAuditLogsResult, - ISignInAuditRepository, + IFindSignInAuditLogsOptions, + IFoundSignInAuditLogsResult, + ISignInAuditRepository, } from './sign-in-audit-repository.interface.js'; export const signInAuditCustomRepositoryExtension: ISignInAuditRepository = { - async createSignInAuditRecord(data: CreateSignInAuditRecordDs): Promise { - const { email, userId, status, signInMethod, ipAddress, userAgent, failureReason } = data; - - const newRecord = new SignInAuditEntity(); - newRecord.email = email?.toLowerCase(); - newRecord.status = status; - newRecord.signInMethod = signInMethod; - newRecord.ipAddress = ipAddress || null; - newRecord.userAgent = userAgent || null; - newRecord.failureReason = failureReason || null; - - if (userId) { - const userRepository = this.manager.getRepository(UserEntity); - const user = await userRepository.findOne({ where: { id: userId } }); - if (user) { - newRecord.user = user; - } - } - - return await this.save(newRecord); - }, - - async findSignInAuditLogs(options: IFindSignInAuditLogsOptions): Promise { - const { companyId, order, page, perPage, dateFrom, dateTo, searchedEmail, status, signInMethod, userId } = options; - - const qb = this.createQueryBuilder('signInAudit') - .leftJoinAndSelect('signInAudit.user', 'user') - .leftJoin('user.company', 'company') - .where('company.id = :companyId', { companyId }); - - if (userId) { - qb.andWhere('user.id = :userId', { userId }); - } - - if (searchedEmail) { - qb.andWhere('signInAudit.email = :email', { email: searchedEmail.toLowerCase() }); - } - - if (status) { - qb.andWhere('signInAudit.status = :status', { status }); - } - - if (signInMethod) { - qb.andWhere('signInAudit.signInMethod = :signInMethod', { signInMethod }); - } - - if (dateFrom && dateTo) { - qb.andWhere('signInAudit.createdAt >= :dateFrom', { dateFrom }); - qb.andWhere('signInAudit.createdAt <= :dateTo', { dateTo }); - } - - qb.orderBy('signInAudit.createdAt', order); - - const rowsCount = await qb.getCount(); - const lastPage = Math.ceil(rowsCount / perPage); - const offset = (page - 1) * perPage; - - qb.limit(perPage); - qb.offset(offset); - - const logs = await qb.getMany(); - - return { - logs, - pagination: { - currentPage: page, - lastPage, - perPage, - total: rowsCount, - }, - }; - }, - - async findSignInAuditLogsByUserId( - userId: string, - options: IFindSignInAuditLogsOptions, - ): Promise { - const { order, page, perPage, dateFrom, dateTo, status, signInMethod } = options; - - const qb = this.createQueryBuilder('signInAudit') - .leftJoinAndSelect('signInAudit.user', 'user') - .where('user.id = :userId', { userId }); - - if (status) { - qb.andWhere('signInAudit.status = :status', { status }); - } - - if (signInMethod) { - qb.andWhere('signInAudit.signInMethod = :signInMethod', { signInMethod }); - } - - if (dateFrom && dateTo) { - qb.andWhere('signInAudit.createdAt >= :dateFrom', { dateFrom }); - qb.andWhere('signInAudit.createdAt <= :dateTo', { dateTo }); - } - - qb.orderBy('signInAudit.createdAt', order); - - const rowsCount = await qb.getCount(); - const lastPage = Math.ceil(rowsCount / perPage); - const offset = (page - 1) * perPage; - - qb.limit(perPage); - qb.offset(offset); - - const logs = await qb.getMany(); - - return { - logs, - pagination: { - currentPage: page, - lastPage, - perPage, - total: rowsCount, - }, - }; - }, + async createSignInAuditRecord(data: CreateSignInAuditRecordDs): Promise { + const { email, userId, status, signInMethod, ipAddress, userAgent, failureReason } = data; + + const newRecord = new SignInAuditEntity(); + newRecord.email = email?.toLowerCase(); + newRecord.status = status; + newRecord.signInMethod = signInMethod; + newRecord.ipAddress = ipAddress || null; + newRecord.userAgent = userAgent || null; + newRecord.failureReason = failureReason || null; + + if (userId) { + const userRepository = this.manager.getRepository(UserEntity); + const user = await userRepository.findOne({ where: { id: userId } }); + if (user) { + newRecord.user = user; + } + } + + return await this.save(newRecord); + }, + + async findSignInAuditLogs(options: IFindSignInAuditLogsOptions): Promise { + const { companyId, order, page, perPage, dateFrom, dateTo, searchedEmail, status, signInMethod, userId } = options; + + const qb = this.createQueryBuilder('signInAudit') + .leftJoinAndSelect('signInAudit.user', 'user') + .leftJoin('user.company', 'company') + .where('company.id = :companyId', { companyId }); + + if (userId) { + qb.andWhere('user.id = :userId', { userId }); + } + + if (searchedEmail) { + qb.andWhere('signInAudit.email = :email', { email: searchedEmail.toLowerCase() }); + } + + if (status) { + qb.andWhere('signInAudit.status = :status', { status }); + } + + if (signInMethod) { + qb.andWhere('signInAudit.signInMethod = :signInMethod', { signInMethod }); + } + + if (dateFrom && dateTo) { + qb.andWhere('signInAudit.createdAt >= :dateFrom', { dateFrom }); + qb.andWhere('signInAudit.createdAt <= :dateTo', { dateTo }); + } + + qb.orderBy('signInAudit.createdAt', order); + + const rowsCount = await qb.getCount(); + const lastPage = Math.ceil(rowsCount / perPage); + const offset = (page - 1) * perPage; + + qb.limit(perPage); + qb.offset(offset); + + const logs = await qb.getMany(); + + return { + logs, + pagination: { + currentPage: page, + lastPage, + perPage, + total: rowsCount, + }, + }; + }, + + async findSignInAuditLogsByUserId( + userId: string, + options: IFindSignInAuditLogsOptions, + ): Promise { + const { order, page, perPage, dateFrom, dateTo, status, signInMethod } = options; + + const qb = this.createQueryBuilder('signInAudit') + .leftJoinAndSelect('signInAudit.user', 'user') + .where('user.id = :userId', { userId }); + + if (status) { + qb.andWhere('signInAudit.status = :status', { status }); + } + + if (signInMethod) { + qb.andWhere('signInAudit.signInMethod = :signInMethod', { signInMethod }); + } + + if (dateFrom && dateTo) { + qb.andWhere('signInAudit.createdAt >= :dateFrom', { dateFrom }); + qb.andWhere('signInAudit.createdAt <= :dateTo', { dateTo }); + } + + qb.orderBy('signInAudit.createdAt', order); + + const rowsCount = await qb.getCount(); + const lastPage = Math.ceil(rowsCount / perPage); + const offset = (page - 1) * perPage; + + qb.limit(perPage); + qb.offset(offset); + + const logs = await qb.getMany(); + + return { + logs, + pagination: { + currentPage: page, + lastPage, + perPage, + total: rowsCount, + }, + }; + }, }; diff --git a/backend/src/entities/user-sign-in-audit/repository/sign-in-audit-repository.interface.ts b/backend/src/entities/user-sign-in-audit/repository/sign-in-audit-repository.interface.ts index 146046d44..a3e6446d4 100644 --- a/backend/src/entities/user-sign-in-audit/repository/sign-in-audit-repository.interface.ts +++ b/backend/src/entities/user-sign-in-audit/repository/sign-in-audit-repository.interface.ts @@ -1,39 +1,39 @@ import { QueryOrderingEnum } from '../../../enums/query-ordering.enum.js'; +import { CreateSignInAuditRecordDs } from '../dto/create-sign-in-audit-record.ds.js'; import { SignInMethodEnum } from '../enums/sign-in-method.enum.js'; import { SignInStatusEnum } from '../enums/sign-in-status.enum.js'; -import { CreateSignInAuditRecordDs } from '../dto/create-sign-in-audit-record.ds.js'; import { SignInAuditEntity } from '../sign-in-audit.entity.js'; export interface ISignInAuditRepository { - createSignInAuditRecord(data: CreateSignInAuditRecordDs): Promise; + createSignInAuditRecord(data: CreateSignInAuditRecordDs): Promise; - findSignInAuditLogs(options: IFindSignInAuditLogsOptions): Promise; + findSignInAuditLogs(options: IFindSignInAuditLogsOptions): Promise; - findSignInAuditLogsByUserId( - userId: string, - options: IFindSignInAuditLogsOptions, - ): Promise; + findSignInAuditLogsByUserId( + userId: string, + options: IFindSignInAuditLogsOptions, + ): Promise; } export interface IFindSignInAuditLogsOptions { - companyId: string; - order: QueryOrderingEnum; - page: number; - perPage: number; - dateFrom?: Date; - dateTo?: Date; - searchedEmail?: string; - status?: SignInStatusEnum; - signInMethod?: SignInMethodEnum; - userId?: string; + companyId: string; + order: QueryOrderingEnum; + page: number; + perPage: number; + dateFrom?: Date; + dateTo?: Date; + searchedEmail?: string; + status?: SignInStatusEnum; + signInMethod?: SignInMethodEnum; + userId?: string; } export interface IFoundSignInAuditLogsResult { - logs: Array; - pagination: { - currentPage: number; - lastPage: number; - perPage: number; - total: number; - }; + logs: Array; + pagination: { + currentPage: number; + lastPage: number; + perPage: number; + total: number; + }; } diff --git a/backend/src/entities/user-sign-in-audit/sign-in-audit.controller.ts b/backend/src/entities/user-sign-in-audit/sign-in-audit.controller.ts index 35ebe7a48..f9eed024d 100644 --- a/backend/src/entities/user-sign-in-audit/sign-in-audit.controller.ts +++ b/backend/src/entities/user-sign-in-audit/sign-in-audit.controller.ts @@ -2,6 +2,7 @@ import { Controller, Get, Inject, Injectable, Query, UseInterceptors } from '@ne import { ApiBearerAuth, ApiOperation, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger'; import { UseCaseType } from '../../common/data-injection.tokens.js'; import { UserId } from '../../decorators/index.js'; +import { Timeout } from '../../decorators/timeout.decorator.js'; import { InTransactionEnum } from '../../enums/index.js'; import { SentryInterceptor } from '../../interceptors/index.js'; import { FindSignInAuditLogsDs } from './dto/find-sign-in-audit-logs.ds.js'; @@ -9,7 +10,6 @@ import { FoundSignInAuditLogsDs } from './dto/found-sign-in-audit-logs.ds.js'; import { SignInMethodEnum } from './enums/sign-in-method.enum.js'; import { SignInStatusEnum } from './enums/sign-in-status.enum.js'; import { IFindSignInAuditLogs } from './use-cases/use-cases.interface.js'; -import { Timeout } from '../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/user-sign-in-audit/sign-in-audit.entity.ts b/backend/src/entities/user-sign-in-audit/sign-in-audit.entity.ts index 70241efab..2ac04e000 100644 --- a/backend/src/entities/user-sign-in-audit/sign-in-audit.entity.ts +++ b/backend/src/entities/user-sign-in-audit/sign-in-audit.entity.ts @@ -1,46 +1,46 @@ import { Column, Entity, JoinColumn, ManyToOne, PrimaryGeneratedColumn, Relation } from 'typeorm'; import { UserEntity } from '../user/user.entity.js'; -import { SignInStatusEnum } from './enums/sign-in-status.enum.js'; import { SignInMethodEnum } from './enums/sign-in-method.enum.js'; +import { SignInStatusEnum } from './enums/sign-in-status.enum.js'; @Entity('signInAudit') export class SignInAuditEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ default: null }) - email: string; + @Column({ default: null }) + email: string; - @Column('enum', { - nullable: false, - enum: SignInStatusEnum, - default: SignInStatusEnum.SUCCESS, - }) - status: SignInStatusEnum; + @Column('enum', { + nullable: false, + enum: SignInStatusEnum, + default: SignInStatusEnum.SUCCESS, + }) + status: SignInStatusEnum; - @Column('enum', { - nullable: false, - enum: SignInMethodEnum, - default: SignInMethodEnum.EMAIL, - }) - signInMethod: SignInMethodEnum; + @Column('enum', { + nullable: false, + enum: SignInMethodEnum, + default: SignInMethodEnum.EMAIL, + }) + signInMethod: SignInMethodEnum; - @Column({ default: null }) - ipAddress: string; + @Column({ default: null }) + ipAddress: string; - @Column({ default: null }) - userAgent: string; + @Column({ default: null }) + userAgent: string; - @Column({ default: null }) - failureReason: string; + @Column({ default: null }) + failureReason: string; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - createdAt: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + createdAt: Date; - @ManyToOne((_) => UserEntity, { onDelete: 'CASCADE', nullable: true }) - @JoinColumn({ name: 'userId' }) - user: Relation; + @ManyToOne((_) => UserEntity, { onDelete: 'CASCADE', nullable: true }) + @JoinColumn({ name: 'userId' }) + user: Relation; - @Column({ nullable: true }) - userId: string; + @Column({ nullable: true }) + userId: string; } diff --git a/backend/src/entities/user-sign-in-audit/sign-in-audit.module.ts b/backend/src/entities/user-sign-in-audit/sign-in-audit.module.ts index 1f9ba5801..2811689c6 100644 --- a/backend/src/entities/user-sign-in-audit/sign-in-audit.module.ts +++ b/backend/src/entities/user-sign-in-audit/sign-in-audit.module.ts @@ -12,23 +12,23 @@ import { FindSignInAuditLogsUseCase } from './use-cases/find-sign-in-audit-logs. @Global() @Module({ - imports: [TypeOrmModule.forFeature([SignInAuditEntity, UserEntity, LogOutEntity])], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.FIND_SIGN_IN_AUDIT_LOGS, - useClass: FindSignInAuditLogsUseCase, - }, - SignInAuditService, - ], - controllers: [SignInAuditController], - exports: [SignInAuditService], + imports: [TypeOrmModule.forFeature([SignInAuditEntity, UserEntity, LogOutEntity])], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.FIND_SIGN_IN_AUDIT_LOGS, + useClass: FindSignInAuditLogsUseCase, + }, + SignInAuditService, + ], + controllers: [SignInAuditController], + exports: [SignInAuditService], }) export class SignInAuditModule { - public configure(consumer: MiddlewareConsumer): any { - consumer.apply(AuthMiddleware).forRoutes({ path: '/sign-in-audit/logs', method: RequestMethod.GET }); - } + public configure(consumer: MiddlewareConsumer): any { + consumer.apply(AuthMiddleware).forRoutes({ path: '/sign-in-audit/logs', method: RequestMethod.GET }); + } } diff --git a/backend/src/entities/user-sign-in-audit/sign-in-audit.service.ts b/backend/src/entities/user-sign-in-audit/sign-in-audit.service.ts index e30a6d6a0..4d0def328 100644 --- a/backend/src/entities/user-sign-in-audit/sign-in-audit.service.ts +++ b/backend/src/entities/user-sign-in-audit/sign-in-audit.service.ts @@ -1,41 +1,41 @@ import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; -import { SignInAuditEntity } from './sign-in-audit.entity.js'; -import { CreateSignInAuditRecordDs } from './dto/create-sign-in-audit-record.ds.js'; import { UserEntity } from '../user/user.entity.js'; +import { CreateSignInAuditRecordDs } from './dto/create-sign-in-audit-record.ds.js'; import { FoundSignInAuditRecordDs } from './dto/found-sign-in-audit-record.ds.js'; +import { SignInAuditEntity } from './sign-in-audit.entity.js'; import { buildFoundSignInAuditRecordDs } from './utils/build-found-sign-in-audit-record-ds.js'; @Injectable() export class SignInAuditService { - constructor( - @InjectRepository(SignInAuditEntity) - private readonly signInAuditRepository: Repository, - @InjectRepository(UserEntity) - private readonly userRepository: Repository, - ) {} + constructor( + @InjectRepository(SignInAuditEntity) + private readonly signInAuditRepository: Repository, + @InjectRepository(UserEntity) + private readonly userRepository: Repository, + ) {} - public async createSignInAuditRecord(data: CreateSignInAuditRecordDs): Promise { - const { email, userId, status, signInMethod, ipAddress, userAgent, failureReason } = data; + public async createSignInAuditRecord(data: CreateSignInAuditRecordDs): Promise { + const { email, userId, status, signInMethod, ipAddress, userAgent, failureReason } = data; - const newRecord = new SignInAuditEntity(); - newRecord.email = email?.toLowerCase(); - newRecord.status = status; - newRecord.signInMethod = signInMethod; - newRecord.ipAddress = ipAddress || null; - newRecord.userAgent = userAgent || null; - newRecord.failureReason = failureReason || null; + const newRecord = new SignInAuditEntity(); + newRecord.email = email?.toLowerCase(); + newRecord.status = status; + newRecord.signInMethod = signInMethod; + newRecord.ipAddress = ipAddress || null; + newRecord.userAgent = userAgent || null; + newRecord.failureReason = failureReason || null; - if (userId) { - const user = await this.userRepository.findOne({ where: { id: userId } }); - if (user) { - newRecord.user = user; - newRecord.userId = user.id; - } - } + if (userId) { + const user = await this.userRepository.findOne({ where: { id: userId } }); + if (user) { + newRecord.user = user; + newRecord.userId = user.id; + } + } - const savedRecord = await this.signInAuditRepository.save(newRecord); - return buildFoundSignInAuditRecordDs(savedRecord); - } + const savedRecord = await this.signInAuditRepository.save(newRecord); + return buildFoundSignInAuditRecordDs(savedRecord); + } } diff --git a/backend/src/entities/user-sign-in-audit/use-cases/find-sign-in-audit-logs.use.case.ts b/backend/src/entities/user-sign-in-audit/use-cases/find-sign-in-audit-logs.use.case.ts index 726390e6e..83460ebd0 100644 --- a/backend/src/entities/user-sign-in-audit/use-cases/find-sign-in-audit-logs.use.case.ts +++ b/backend/src/entities/user-sign-in-audit/use-cases/find-sign-in-audit-logs.use.case.ts @@ -15,108 +15,108 @@ import { IFindSignInAuditLogs } from './use-cases.interface.js'; @Injectable() export class FindSignInAuditLogsUseCase - extends AbstractUseCase - implements IFindSignInAuditLogs + extends AbstractUseCase + implements IFindSignInAuditLogs { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: FindSignInAuditLogsDs): Promise { - const { userId, companyId, query } = inputData; + protected async implementation(inputData: FindSignInAuditLogsDs): Promise { + const { userId, companyId, query } = inputData; - const user = await this._dbContext.userRepository.findOne({ - where: { id: userId }, - relations: ['company'], - }); + const user = await this._dbContext.userRepository.findOne({ + where: { id: userId }, + relations: ['company'], + }); - if (!user || user.company?.id !== companyId) { - throw new HttpException( - { - message: Messages.COMPANY_NOT_FOUND, - }, - HttpStatus.FORBIDDEN, - ); - } + if (!user || user.company?.id !== companyId) { + throw new HttpException( + { + message: Messages.COMPANY_NOT_FOUND, + }, + HttpStatus.FORBIDDEN, + ); + } - let order = query.order as QueryOrderingEnum; - let page = query.page; - let perPage = query.perPage; - const dateFrom = query.dateFrom; - const dateTo = query.dateTo; - const searchedEmail = query.email?.toLowerCase(); - const status = query.status; - const signInMethod = query.signInMethod; + let order = query.order as QueryOrderingEnum; + let page = query.page; + let perPage = query.perPage; + const dateFrom = query.dateFrom; + const dateTo = query.dateTo; + const searchedEmail = query.email?.toLowerCase(); + const status = query.status; + const signInMethod = query.signInMethod; - if (status) { - const statusValidationResult = validateStringWithEnum(status, SignInStatusEnum); - if (!statusValidationResult) { - throw new HttpException( - { - message: Messages.INVALID_SIGN_IN_STATUS, - }, - HttpStatus.BAD_REQUEST, - ); - } - } + if (status) { + const statusValidationResult = validateStringWithEnum(status, SignInStatusEnum); + if (!statusValidationResult) { + throw new HttpException( + { + message: Messages.INVALID_SIGN_IN_STATUS, + }, + HttpStatus.BAD_REQUEST, + ); + } + } - if (signInMethod) { - const methodValidationResult = validateStringWithEnum(signInMethod, SignInMethodEnum); - if (!methodValidationResult) { - throw new HttpException( - { - message: Messages.INVALID_SIGN_IN_METHOD, - }, - HttpStatus.BAD_REQUEST, - ); - } - } + if (signInMethod) { + const methodValidationResult = validateStringWithEnum(signInMethod, SignInMethodEnum); + if (!methodValidationResult) { + throw new HttpException( + { + message: Messages.INVALID_SIGN_IN_METHOD, + }, + HttpStatus.BAD_REQUEST, + ); + } + } - if (!order || order !== QueryOrderingEnum.ASC) { - order = QueryOrderingEnum.DESC; - } - if (!page || page <= 0) { - page = 1; - } - if (!perPage || perPage <= 0) { - perPage = Constants.DEFAULT_LOG_ROWS_LIMIT; - } + if (!order || order !== QueryOrderingEnum.ASC) { + order = QueryOrderingEnum.DESC; + } + if (!page || page <= 0) { + page = 1; + } + if (!perPage || perPage <= 0) { + perPage = Constants.DEFAULT_LOG_ROWS_LIMIT; + } - let searchedDateFrom: Date = null; - let searchedDateTo: Date = null; - if (dateFrom && dateTo) { - let dateFromParsed = Date.parse(dateFrom); - let dateToParsed = Date.parse(dateTo); - const dateFromMs = new Date(dateFromParsed).getTime(); - const dateToMs = new Date(dateToParsed).getTime(); - if (dateFromMs > dateToMs) { - const tmpDate = dateFromParsed; - dateFromParsed = dateToParsed; - dateToParsed = tmpDate; - } - searchedDateFrom = new Date(dateFromParsed); - searchedDateTo = new Date(dateToParsed); - } + let searchedDateFrom: Date = null; + let searchedDateTo: Date = null; + if (dateFrom && dateTo) { + let dateFromParsed = Date.parse(dateFrom); + let dateToParsed = Date.parse(dateTo); + const dateFromMs = new Date(dateFromParsed).getTime(); + const dateToMs = new Date(dateToParsed).getTime(); + if (dateFromMs > dateToMs) { + const tmpDate = dateFromParsed; + dateFromParsed = dateToParsed; + dateToParsed = tmpDate; + } + searchedDateFrom = new Date(dateFromParsed); + searchedDateTo = new Date(dateToParsed); + } - const { logs, pagination } = await this._dbContext.signInAuditRepository.findSignInAuditLogs({ - companyId, - order, - page, - perPage, - dateFrom: searchedDateFrom, - dateTo: searchedDateTo, - searchedEmail, - status, - signInMethod, - userId, - }); + const { logs, pagination } = await this._dbContext.signInAuditRepository.findSignInAuditLogs({ + companyId, + order, + page, + perPage, + dateFrom: searchedDateFrom, + dateTo: searchedDateTo, + searchedEmail, + status, + signInMethod, + userId, + }); - return { - logs: logs.map((log) => buildFoundSignInAuditRecordDs(log)), - pagination, - }; - } + return { + logs: logs.map((log) => buildFoundSignInAuditRecordDs(log)), + pagination, + }; + } } diff --git a/backend/src/entities/user-sign-in-audit/use-cases/use-cases.interface.ts b/backend/src/entities/user-sign-in-audit/use-cases/use-cases.interface.ts index d887058b8..2d162767f 100644 --- a/backend/src/entities/user-sign-in-audit/use-cases/use-cases.interface.ts +++ b/backend/src/entities/user-sign-in-audit/use-cases/use-cases.interface.ts @@ -3,5 +3,5 @@ import { FindSignInAuditLogsDs } from '../dto/find-sign-in-audit-logs.ds.js'; import { FoundSignInAuditLogsDs } from '../dto/found-sign-in-audit-logs.ds.js'; export interface IFindSignInAuditLogs { - execute(inputData: FindSignInAuditLogsDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: FindSignInAuditLogsDs, inTransaction: InTransactionEnum): Promise; } diff --git a/backend/src/entities/user-sign-in-audit/utils/build-found-sign-in-audit-record-ds.ts b/backend/src/entities/user-sign-in-audit/utils/build-found-sign-in-audit-record-ds.ts index 6358b7c15..0968e1267 100644 --- a/backend/src/entities/user-sign-in-audit/utils/build-found-sign-in-audit-record-ds.ts +++ b/backend/src/entities/user-sign-in-audit/utils/build-found-sign-in-audit-record-ds.ts @@ -1,16 +1,16 @@ -import { SignInAuditEntity } from '../sign-in-audit.entity.js'; import { FoundSignInAuditRecordDs } from '../dto/found-sign-in-audit-record.ds.js'; +import { SignInAuditEntity } from '../sign-in-audit.entity.js'; export function buildFoundSignInAuditRecordDs(entity: SignInAuditEntity): FoundSignInAuditRecordDs { - return { - id: entity.id, - email: entity.email, - status: entity.status, - signInMethod: entity.signInMethod, - ipAddress: entity.ipAddress, - userAgent: entity.userAgent, - failureReason: entity.failureReason, - createdAt: entity.createdAt, - userId: entity.user?.id || null, - }; + return { + id: entity.id, + email: entity.email, + status: entity.status, + signInMethod: entity.signInMethod, + ipAddress: entity.ipAddress, + userAgent: entity.userAgent, + failureReason: entity.failureReason, + createdAt: entity.createdAt, + userId: entity.user?.id || null, + }; } diff --git a/backend/src/entities/user/application/data-structures/change-user-email.ds.ts b/backend/src/entities/user/application/data-structures/change-user-email.ds.ts index 9a144fcfa..1dfac1ad5 100644 --- a/backend/src/entities/user/application/data-structures/change-user-email.ds.ts +++ b/backend/src/entities/user/application/data-structures/change-user-email.ds.ts @@ -1,4 +1,4 @@ export class ChangeUserEmailDs { - newEmail: string; - verificationString: string; + newEmail: string; + verificationString: string; } diff --git a/backend/src/entities/user/application/data-structures/change-user-name.ds.ts b/backend/src/entities/user/application/data-structures/change-user-name.ds.ts index b1484292a..5e6440552 100644 --- a/backend/src/entities/user/application/data-structures/change-user-name.ds.ts +++ b/backend/src/entities/user/application/data-structures/change-user-name.ds.ts @@ -1,8 +1,8 @@ import { ApiProperty } from '@nestjs/swagger'; export class ChangeUserNameDS { - id: string; + id: string; - @ApiProperty() - name: string; + @ApiProperty() + name: string; } diff --git a/backend/src/entities/user/application/data-structures/change-usual-user-password.ds.ts b/backend/src/entities/user/application/data-structures/change-usual-user-password.ds.ts index 295501afc..829d36286 100644 --- a/backend/src/entities/user/application/data-structures/change-usual-user-password.ds.ts +++ b/backend/src/entities/user/application/data-structures/change-usual-user-password.ds.ts @@ -1,32 +1,32 @@ import { ApiProperty } from '@nestjs/swagger'; -import { IsNotEmpty, IsString, IsEmail, IsStrongPassword, MaxLength } from 'class-validator'; +import { IsEmail, IsNotEmpty, IsString, IsStrongPassword, MaxLength } from 'class-validator'; export class ChangeUsualUserPasswordDto { - @ApiProperty() - @IsNotEmpty() - @IsString() - @IsEmail() - email: string; + @ApiProperty() + @IsNotEmpty() + @IsString() + @IsEmail() + email: string; - @ApiProperty() - @IsNotEmpty() - @IsString() - @MaxLength(255) - @IsStrongPassword({ - minLength: 8, - minLowercase: 1, - minUppercase: 1, - minNumbers: 1, - minSymbols: 0, - }) - newPassword: string; + @ApiProperty() + @IsNotEmpty() + @IsString() + @MaxLength(255) + @IsStrongPassword({ + minLength: 8, + minLowercase: 1, + minUppercase: 1, + minNumbers: 1, + minSymbols: 0, + }) + newPassword: string; - @ApiProperty() - @IsNotEmpty() - @IsString() - oldPassword: string; + @ApiProperty() + @IsNotEmpty() + @IsString() + oldPassword: string; } export class ChangeUsualUserPasswordDs extends ChangeUsualUserPasswordDto { - userId: string; -} \ No newline at end of file + userId: string; +} diff --git a/backend/src/entities/user/application/data-structures/create-user.ds.ts b/backend/src/entities/user/application/data-structures/create-user.ds.ts index 8d05eba2f..a0f99a564 100644 --- a/backend/src/entities/user/application/data-structures/create-user.ds.ts +++ b/backend/src/entities/user/application/data-structures/create-user.ds.ts @@ -1,4 +1,4 @@ export class CreateUserDs { - id: string; - gclidValue?: string; + id: string; + gclidValue?: string; } diff --git a/backend/src/entities/user/application/data-structures/demo-user-account-register.ds.ts b/backend/src/entities/user/application/data-structures/demo-user-account-register.ds.ts index d4b7d0674..abcc7de1c 100644 --- a/backend/src/entities/user/application/data-structures/demo-user-account-register.ds.ts +++ b/backend/src/entities/user/application/data-structures/demo-user-account-register.ds.ts @@ -1,6 +1,6 @@ export class SaaSRegisterDemoUserAccountDS { - email: string; - gclidValue: string; - companyName: string; - companyId: string; + email: string; + gclidValue: string; + companyName: string; + companyId: string; } diff --git a/backend/src/entities/user/application/data-structures/find-user.ds.ts b/backend/src/entities/user/application/data-structures/find-user.ds.ts index 6f65372f5..be4cac6f5 100644 --- a/backend/src/entities/user/application/data-structures/find-user.ds.ts +++ b/backend/src/entities/user/application/data-structures/find-user.ds.ts @@ -1,4 +1,4 @@ export class FindUserDs { - id: string; - gclidValue?: string; + id: string; + gclidValue?: string; } diff --git a/backend/src/entities/user/application/data-structures/found-user-in-group.ds.ts b/backend/src/entities/user/application/data-structures/found-user-in-group.ds.ts index 88aea059b..9cd264099 100644 --- a/backend/src/entities/user/application/data-structures/found-user-in-group.ds.ts +++ b/backend/src/entities/user/application/data-structures/found-user-in-group.ds.ts @@ -2,24 +2,24 @@ import { ApiProperty } from '@nestjs/swagger'; import { ExternalRegistrationProviderEnum } from '../../enums/external-registration-provider.enum.js'; export class FoundUserInGroupDs { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - isActive: boolean; + @ApiProperty() + isActive: boolean; - @ApiProperty() - email: string; + @ApiProperty() + email: string; - @ApiProperty() - createdAt: Date; + @ApiProperty() + createdAt: Date; - @ApiProperty() - name: string; + @ApiProperty() + name: string; - @ApiProperty() - suspended: boolean; + @ApiProperty() + suspended: boolean; - @ApiProperty() - externalRegistrationProvider: ExternalRegistrationProviderEnum; + @ApiProperty() + externalRegistrationProvider: ExternalRegistrationProviderEnum; } diff --git a/backend/src/entities/user/application/data-structures/operation-result-message.ds.ts b/backend/src/entities/user/application/data-structures/operation-result-message.ds.ts index 0645f033b..bc1f8e0f0 100644 --- a/backend/src/entities/user/application/data-structures/operation-result-message.ds.ts +++ b/backend/src/entities/user/application/data-structures/operation-result-message.ds.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; export class OperationResultMessageDs { - @ApiProperty() - message: string; + @ApiProperty() + message: string; } diff --git a/backend/src/entities/user/application/data-structures/otp-secret.ds.ts b/backend/src/entities/user/application/data-structures/otp-secret.ds.ts index 6d7e7bcc5..1b6260990 100644 --- a/backend/src/entities/user/application/data-structures/otp-secret.ds.ts +++ b/backend/src/entities/user/application/data-structures/otp-secret.ds.ts @@ -1,9 +1,9 @@ -import { ApiProperty } from "@nestjs/swagger"; +import { ApiProperty } from '@nestjs/swagger'; export class OtpSecretDS { - @ApiProperty() - otpauth_url: string; + @ApiProperty() + otpauth_url: string; - @ApiProperty() - qrCode: string; + @ApiProperty() + qrCode: string; } diff --git a/backend/src/entities/user/application/data-structures/otp-validation-result.ds.ts b/backend/src/entities/user/application/data-structures/otp-validation-result.ds.ts index 0b582a1aa..13c7f8a88 100644 --- a/backend/src/entities/user/application/data-structures/otp-validation-result.ds.ts +++ b/backend/src/entities/user/application/data-structures/otp-validation-result.ds.ts @@ -1,11 +1,11 @@ import { ApiProperty } from '@nestjs/swagger'; export class OtpValidationResultDS { - @ApiProperty() - validated: boolean; + @ApiProperty() + validated: boolean; } export class OtpDisablingResultDS { - @ApiProperty() - disabled: boolean; + @ApiProperty() + disabled: boolean; } diff --git a/backend/src/entities/user/application/data-structures/register-user-ds.ts b/backend/src/entities/user/application/data-structures/register-user-ds.ts index 178b4e65a..7f73330f5 100644 --- a/backend/src/entities/user/application/data-structures/register-user-ds.ts +++ b/backend/src/entities/user/application/data-structures/register-user-ds.ts @@ -1,11 +1,11 @@ import { UserRoleEnum } from '../../enums/user-role.enum.js'; export class RegisterUserDs { - gclidValue: string; - email: string; - password: string; - isActive: boolean; - name: string; - role?: UserRoleEnum; - samlNameId?: string; + gclidValue: string; + email: string; + password: string; + isActive: boolean; + name: string; + role?: UserRoleEnum; + samlNameId?: string; } diff --git a/backend/src/entities/user/application/data-structures/registered-user.ds.ts b/backend/src/entities/user/application/data-structures/registered-user.ds.ts index e9be3f8eb..9d102847e 100644 --- a/backend/src/entities/user/application/data-structures/registered-user.ds.ts +++ b/backend/src/entities/user/application/data-structures/registered-user.ds.ts @@ -1,20 +1,20 @@ import { ApiProperty } from '@nestjs/swagger'; -import { IToken } from '../../utils/generate-gwt-token.js'; import { ExternalRegistrationProviderEnum } from '../../enums/external-registration-provider.enum.js'; +import { IToken } from '../../utils/generate-gwt-token.js'; export class RegisteredUserDs { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - email: string; + @ApiProperty() + email: string; - @ApiProperty() - token: IToken; + @ApiProperty() + token: IToken; - @ApiProperty() - name: string; + @ApiProperty() + name: string; - @ApiProperty() - externalRegistrationProvider: ExternalRegistrationProviderEnum; + @ApiProperty() + externalRegistrationProvider: ExternalRegistrationProviderEnum; } diff --git a/backend/src/entities/user/application/data-structures/reset-usual-user-password.ds.ts b/backend/src/entities/user/application/data-structures/reset-usual-user-password.ds.ts index a929fb7dc..824845513 100644 --- a/backend/src/entities/user/application/data-structures/reset-usual-user-password.ds.ts +++ b/backend/src/entities/user/application/data-structures/reset-usual-user-password.ds.ts @@ -1,4 +1,4 @@ export class ResetUsualUserPasswordDs { - verificationString: string; - newUserPassword: string; + verificationString: string; + newUserPassword: string; } diff --git a/backend/src/entities/user/application/data-structures/save-user-settings.ds.ts b/backend/src/entities/user/application/data-structures/save-user-settings.ds.ts index 50ebe2617..95883b425 100644 --- a/backend/src/entities/user/application/data-structures/save-user-settings.ds.ts +++ b/backend/src/entities/user/application/data-structures/save-user-settings.ds.ts @@ -1,4 +1,4 @@ export class SaveUserSettingsDs { - userSettings: string; - userId: string; -} \ No newline at end of file + userSettings: string; + userId: string; +} diff --git a/backend/src/entities/user/application/data-structures/toggle-connection-display-mode.ds.ts b/backend/src/entities/user/application/data-structures/toggle-connection-display-mode.ds.ts index b22991846..fe9c7ff4e 100644 --- a/backend/src/entities/user/application/data-structures/toggle-connection-display-mode.ds.ts +++ b/backend/src/entities/user/application/data-structures/toggle-connection-display-mode.ds.ts @@ -1,4 +1,4 @@ export class ToggleConnectionDisplayModeDs { - userId: string; - displayMode: boolean; -} \ No newline at end of file + userId: string; + displayMode: boolean; +} diff --git a/backend/src/entities/user/application/data-structures/usual-login.ds.ts b/backend/src/entities/user/application/data-structures/usual-login.ds.ts index d53cba8bd..1416cab9e 100644 --- a/backend/src/entities/user/application/data-structures/usual-login.ds.ts +++ b/backend/src/entities/user/application/data-structures/usual-login.ds.ts @@ -1,20 +1,20 @@ import { ApiProperty } from '@nestjs/swagger'; export class UsualLoginDs { - @ApiProperty() - email: string; + @ApiProperty() + email: string; - @ApiProperty() - password: string; + @ApiProperty() + password: string; - @ApiProperty() - companyId: string; + @ApiProperty() + companyId: string; - gclidValue: string; + gclidValue: string; - request_domain: string; + request_domain: string; - ipAddress?: string; + ipAddress?: string; - userAgent?: string; + userAgent?: string; } diff --git a/backend/src/entities/user/application/data-structures/usual-register-user.ds.ts b/backend/src/entities/user/application/data-structures/usual-register-user.ds.ts index 99baa8a33..c25537baf 100644 --- a/backend/src/entities/user/application/data-structures/usual-register-user.ds.ts +++ b/backend/src/entities/user/application/data-structures/usual-register-user.ds.ts @@ -2,26 +2,26 @@ import { ApiProperty } from '@nestjs/swagger'; import { UserRoleEnum } from '../../enums/user-role.enum.js'; class UsualRegisterUserDs { - @ApiProperty() - email: string; + @ApiProperty() + email: string; - @ApiProperty() - password: string; + @ApiProperty() + password: string; - @ApiProperty() - gclidValue: string; + @ApiProperty() + gclidValue: string; - @ApiProperty() - name: string; + @ApiProperty() + name: string; } export class SaasUsualUserRegisterDS extends UsualRegisterUserDs { - @ApiProperty({ required: true }) - companyId: string; + @ApiProperty({ required: true }) + companyId: string; - @ApiProperty({ required: false, enum: UserRoleEnum }) - userRole?: UserRoleEnum; + @ApiProperty({ required: false, enum: UserRoleEnum }) + userRole?: UserRoleEnum; - @ApiProperty({ required: false }) - companyName?: string; + @ApiProperty({ required: false }) + companyName?: string; } diff --git a/backend/src/entities/user/application/data-structures/verify-otp.ds.ts b/backend/src/entities/user/application/data-structures/verify-otp.ds.ts index 8b9f7ef83..54818d035 100644 --- a/backend/src/entities/user/application/data-structures/verify-otp.ds.ts +++ b/backend/src/entities/user/application/data-structures/verify-otp.ds.ts @@ -1,12 +1,12 @@ import { ApiProperty } from '@nestjs/swagger'; export class VerifyOtpDS { - userId: string; + userId: string; - @ApiProperty() - otpToken: string; + @ApiProperty() + otpToken: string; - ipAddress?: string; + ipAddress?: string; - userAgent?: string; + userAgent?: string; } diff --git a/backend/src/entities/user/dto/delete-user-account-request.dto.ts b/backend/src/entities/user/dto/delete-user-account-request.dto.ts index 881b5713f..97805f433 100644 --- a/backend/src/entities/user/dto/delete-user-account-request.dto.ts +++ b/backend/src/entities/user/dto/delete-user-account-request.dto.ts @@ -2,13 +2,13 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsOptional, IsString } from 'class-validator'; export class DeleteUserAccountDTO { - @ApiProperty() - @IsOptional() - @IsString() - reason: string; + @ApiProperty() + @IsOptional() + @IsString() + reason: string; - @ApiProperty() - @IsOptional() - @IsString() - message: string; + @ApiProperty() + @IsOptional() + @IsString() + message: string; } diff --git a/backend/src/entities/user/dto/email.dto.ts b/backend/src/entities/user/dto/email.dto.ts index 617cb8750..969efa13a 100644 --- a/backend/src/entities/user/dto/email.dto.ts +++ b/backend/src/entities/user/dto/email.dto.ts @@ -2,9 +2,9 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsEmail, IsNotEmpty, IsString } from 'class-validator'; export class EmailDto { - @ApiProperty() - @IsString() - @IsEmail() - @IsNotEmpty() - email: string; + @ApiProperty() + @IsString() + @IsEmail() + @IsNotEmpty() + email: string; } diff --git a/backend/src/entities/user/dto/found-user.dto.ts b/backend/src/entities/user/dto/found-user.dto.ts index 4b9889835..2f16d482e 100644 --- a/backend/src/entities/user/dto/found-user.dto.ts +++ b/backend/src/entities/user/dto/found-user.dto.ts @@ -3,103 +3,103 @@ import { ExternalRegistrationProviderEnum } from '../enums/external-registration import { UserRoleEnum } from '../enums/user-role.enum.js'; export class CompanyIdDS { - @ApiProperty() - id: string; + @ApiProperty() + id: string; } export class FoundUserDto { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - isActive: boolean; + @ApiProperty() + isActive: boolean; - @ApiProperty() - email: string; + @ApiProperty() + email: string; - @ApiProperty({ type: Date }) - createdAt: Date; + @ApiProperty({ type: Date }) + createdAt: Date; - @ApiProperty() - suspended: boolean; + @ApiProperty() + suspended: boolean; - @ApiProperty({ required: false, type: String }) - intercom_hash?: string; + @ApiProperty({ required: false, type: String }) + intercom_hash?: string; - @ApiProperty() - name: string; + @ApiProperty() + name: string; - @ApiProperty() - is_2fa_enabled: boolean; + @ApiProperty() + is_2fa_enabled: boolean; - @ApiProperty({ enum: UserRoleEnum }) - role: UserRoleEnum; + @ApiProperty({ enum: UserRoleEnum }) + role: UserRoleEnum; - @ApiProperty({ required: false }) - company?: CompanyIdDS; + @ApiProperty({ required: false }) + company?: CompanyIdDS; - @ApiProperty({ enum: ExternalRegistrationProviderEnum }) - externalRegistrationProvider: ExternalRegistrationProviderEnum; + @ApiProperty({ enum: ExternalRegistrationProviderEnum }) + externalRegistrationProvider: ExternalRegistrationProviderEnum; - @ApiProperty({ default: true }) - show_test_connections: boolean; + @ApiProperty({ default: true }) + show_test_connections: boolean; } export class SimpleFoundUserInfoDs { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - isActive: boolean; + @ApiProperty() + isActive: boolean; - @ApiProperty() - email: string; + @ApiProperty() + email: string; - @ApiProperty() - createdAt: Date; + @ApiProperty() + createdAt: Date; - @ApiProperty() - suspended: boolean; + @ApiProperty() + suspended: boolean; - @ApiProperty() - name: string; + @ApiProperty() + name: string; - @ApiProperty() - is_2fa_enabled: boolean; + @ApiProperty() + is_2fa_enabled: boolean; - @ApiProperty({ enum: UserRoleEnum }) - role: UserRoleEnum; + @ApiProperty({ enum: UserRoleEnum }) + role: UserRoleEnum; - @ApiProperty({ enum: ExternalRegistrationProviderEnum }) - externalRegistrationProvider: ExternalRegistrationProviderEnum; + @ApiProperty({ enum: ExternalRegistrationProviderEnum }) + externalRegistrationProvider: ExternalRegistrationProviderEnum; } export class UserGroupMembershipDto { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - title: string; + @ApiProperty() + title: string; } export class UserConnectionMembershipDto { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - title: string; + @ApiProperty() + title: string; - @ApiProperty() - database: string; + @ApiProperty() + database: string; - @ApiProperty({ type: UserConnectionMembershipDto, isArray: true }) - groups: Array; + @ApiProperty({ type: UserConnectionMembershipDto, isArray: true }) + groups: Array; } export class SimpleFoundUserInCompanyInfoDs extends SimpleFoundUserInfoDs { - @ApiProperty() - has_groups: boolean; + @ApiProperty() + has_groups: boolean; - @ApiProperty({ type: UserConnectionMembershipDto, isArray: true }) - user_membership: Array; + @ApiProperty({ type: UserConnectionMembershipDto, isArray: true }) + user_membership: Array; } diff --git a/backend/src/entities/user/dto/login-user.dto.ts b/backend/src/entities/user/dto/login-user.dto.ts index 9139189fc..7c988e3be 100644 --- a/backend/src/entities/user/dto/login-user.dto.ts +++ b/backend/src/entities/user/dto/login-user.dto.ts @@ -2,21 +2,21 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsEmail, IsNotEmpty, IsOptional, IsString, IsUUID, MaxLength } from 'class-validator'; export class LoginUserDto { - @ApiProperty() - @IsNotEmpty() - @IsString() - @IsEmail() - readonly email: string; + @ApiProperty() + @IsNotEmpty() + @IsString() + @IsEmail() + readonly email: string; - @IsNotEmpty() - @ApiProperty() - @IsString() - @MaxLength(255) - readonly password: string; + @IsNotEmpty() + @ApiProperty() + @IsString() + @MaxLength(255) + readonly password: string; - @ApiProperty() - @IsOptional() - @IsString() - @IsUUID() - readonly companyId: string; + @ApiProperty() + @IsOptional() + @IsString() + @IsUUID() + readonly companyId: string; } diff --git a/backend/src/entities/user/dto/otp-token.dto.ts b/backend/src/entities/user/dto/otp-token.dto.ts index 4cfee5dfa..484906ee0 100644 --- a/backend/src/entities/user/dto/otp-token.dto.ts +++ b/backend/src/entities/user/dto/otp-token.dto.ts @@ -2,9 +2,9 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty, IsString, MaxLength } from 'class-validator'; export class OtpTokenDto { - @ApiProperty() - @IsNotEmpty() - @IsString() - @MaxLength(12) - otpToken: string; + @ApiProperty() + @IsNotEmpty() + @IsString() + @MaxLength(12) + otpToken: string; } diff --git a/backend/src/entities/user/dto/password.dto.ts b/backend/src/entities/user/dto/password.dto.ts index 0e021e2af..f5389c941 100644 --- a/backend/src/entities/user/dto/password.dto.ts +++ b/backend/src/entities/user/dto/password.dto.ts @@ -2,16 +2,16 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty, IsString, IsStrongPassword, MaxLength } from 'class-validator'; export class PasswordDto { - @ApiProperty() - @IsNotEmpty() - @IsString() - @MaxLength(255) - @IsStrongPassword({ - minLength: 8, - minLowercase: 1, - minUppercase: 1, - minNumbers: 1, - minSymbols: 0, - }) - password: string; + @ApiProperty() + @IsNotEmpty() + @IsString() + @MaxLength(255) + @IsStrongPassword({ + minLength: 8, + minLowercase: 1, + minUppercase: 1, + minNumbers: 1, + minSymbols: 0, + }) + password: string; } diff --git a/backend/src/entities/user/dto/request-rest-user-password.dto.ts b/backend/src/entities/user/dto/request-rest-user-password.dto.ts index 61a912119..a8bb6e10c 100644 --- a/backend/src/entities/user/dto/request-rest-user-password.dto.ts +++ b/backend/src/entities/user/dto/request-rest-user-password.dto.ts @@ -2,15 +2,15 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsEmail, IsNotEmpty, IsString, IsUUID } from 'class-validator'; export class RequestRestUserPasswordDto { - @ApiProperty() - @IsNotEmpty() - @IsString() - @IsEmail() - email: string; + @ApiProperty() + @IsNotEmpty() + @IsString() + @IsEmail() + email: string; - @ApiProperty() - @IsNotEmpty() - @IsString() - @IsUUID() - companyId: string; + @ApiProperty() + @IsNotEmpty() + @IsString() + @IsUUID() + companyId: string; } diff --git a/backend/src/entities/user/dto/user-name.dto.ts b/backend/src/entities/user/dto/user-name.dto.ts index bfa1d7a43..74d9e1f3c 100644 --- a/backend/src/entities/user/dto/user-name.dto.ts +++ b/backend/src/entities/user/dto/user-name.dto.ts @@ -2,8 +2,8 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsNotEmpty, IsString } from 'class-validator'; export class UserNameDto { - @ApiProperty() - @IsString() - @IsNotEmpty() - name: string; + @ApiProperty() + @IsString() + @IsNotEmpty() + name: string; } diff --git a/backend/src/entities/user/dto/user-settings-data-request.dto.ts b/backend/src/entities/user/dto/user-settings-data-request.dto.ts index 1db73fe96..798b70297 100644 --- a/backend/src/entities/user/dto/user-settings-data-request.dto.ts +++ b/backend/src/entities/user/dto/user-settings-data-request.dto.ts @@ -2,9 +2,9 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsJSON, IsNotEmpty, IsString } from 'class-validator'; export class UserSettingsDataRequestDto { - @ApiProperty() - @IsString() - @IsNotEmpty() - @IsJSON() - userSettings: string; + @ApiProperty() + @IsString() + @IsNotEmpty() + @IsJSON() + userSettings: string; } diff --git a/backend/src/entities/user/enums/external-registration-provider.enum.ts b/backend/src/entities/user/enums/external-registration-provider.enum.ts index aceb02fa2..419003767 100644 --- a/backend/src/entities/user/enums/external-registration-provider.enum.ts +++ b/backend/src/entities/user/enums/external-registration-provider.enum.ts @@ -1,5 +1,5 @@ export enum ExternalRegistrationProviderEnum { - GOOGLE = 'GOOGLE', - GITHUB = 'GITHUB', - SAML = 'SAML', + GOOGLE = 'GOOGLE', + GITHUB = 'GITHUB', + SAML = 'SAML', } diff --git a/backend/src/entities/user/enums/jwt-scopes.enum.ts b/backend/src/entities/user/enums/jwt-scopes.enum.ts index 748a536b8..6d92ab326 100644 --- a/backend/src/entities/user/enums/jwt-scopes.enum.ts +++ b/backend/src/entities/user/enums/jwt-scopes.enum.ts @@ -1,3 +1,3 @@ export enum JwtScopesEnum { - TWO_FA_ENABLE = '2fa_enable', + TWO_FA_ENABLE = '2fa_enable', } diff --git a/backend/src/entities/user/enums/user-role.enum.ts b/backend/src/entities/user/enums/user-role.enum.ts index 78022ba12..b6793ff41 100644 --- a/backend/src/entities/user/enums/user-role.enum.ts +++ b/backend/src/entities/user/enums/user-role.enum.ts @@ -1,5 +1,5 @@ export enum UserRoleEnum { - ADMIN = 'ADMIN', - USER = 'USER', - DB_ADMIN = 'DB_ADMIN', + ADMIN = 'ADMIN', + USER = 'USER', + DB_ADMIN = 'DB_ADMIN', } diff --git a/backend/src/entities/user/repository/user-custom-repository-extension.ts b/backend/src/entities/user/repository/user-custom-repository-extension.ts index 5605a405e..e8299c206 100644 --- a/backend/src/entities/user/repository/user-custom-repository-extension.ts +++ b/backend/src/entities/user/repository/user-custom-repository-extension.ts @@ -7,265 +7,265 @@ import { UserEntity } from '../user.entity.js'; import { IUserRepository } from './user.repository.interface.js'; export const userCustomRepositoryExtension: IUserRepository = { - async createUser(userData: CreateUserDs): Promise { - const newUser: UserEntity = new UserEntity(); - newUser.id = userData.id; - newUser.isActive = true; - newUser.gclid = userData.gclidValue || null; - return await this.save(newUser); - }, + async createUser(userData: CreateUserDs): Promise { + const newUser: UserEntity = new UserEntity(); + newUser.id = userData.id; + newUser.isActive = true; + newUser.gclid = userData.gclidValue || null; + return await this.save(newUser); + }, - async saveRegisteringUser( - userData: RegisterUserDs, - externalRegistrationProvider: ExternalRegistrationProviderEnum = null, - ): Promise { - const newUser: UserEntity = new UserEntity(); - newUser.gclid = userData.gclidValue; - newUser.email = userData.email.toLowerCase(); - newUser.password = userData.password; - newUser.isActive = userData.isActive; - newUser.name = userData.name; - newUser.role = userData.role ? userData.role : UserRoleEnum.USER; - newUser.externalRegistrationProvider = externalRegistrationProvider; - return await this.save(newUser); - }, + async saveRegisteringUser( + userData: RegisterUserDs, + externalRegistrationProvider: ExternalRegistrationProviderEnum = null, + ): Promise { + const newUser: UserEntity = new UserEntity(); + newUser.gclid = userData.gclidValue; + newUser.email = userData.email.toLowerCase(); + newUser.password = userData.password; + newUser.isActive = userData.isActive; + newUser.name = userData.name; + newUser.role = userData.role ? userData.role : UserRoleEnum.USER; + newUser.externalRegistrationProvider = externalRegistrationProvider; + return await this.save(newUser); + }, - async findOneUserById(userId: string): Promise { - const userQb = this.createQueryBuilder('user') - .leftJoinAndSelect('user.company', 'company') - .andWhere('user.id = :userId', { userId: userId }); - return await userQb.getOne(); - }, + async findOneUserById(userId: string): Promise { + const userQb = this.createQueryBuilder('user') + .leftJoinAndSelect('user.company', 'company') + .andWhere('user.id = :userId', { userId: userId }); + return await userQb.getOne(); + }, - async findOneUserWithUserAction(userId: string): Promise { - const userQb = this.createQueryBuilder('user') - .leftJoinAndSelect('user.user_action', 'user_action') - .andWhere('user.id = :userId', { userId: userId }); - return await userQb.getOne(); - }, + async findOneUserWithUserAction(userId: string): Promise { + const userQb = this.createQueryBuilder('user') + .leftJoinAndSelect('user.user_action', 'user_action') + .andWhere('user.id = :userId', { userId: userId }); + return await userQb.getOne(); + }, - async findOneUserByEmail( - email: string, - externalRegistrationProvider: ExternalRegistrationProviderEnum = null, - samlNameId: string = null, - ): Promise { - const userQb = this.createQueryBuilder('user').where('user.email = :userEmail', { - userEmail: email?.toLowerCase(), - }); - if (externalRegistrationProvider) { - userQb.andWhere('user.externalRegistrationProvider = :externalRegistrationProvider', { - externalRegistrationProvider: externalRegistrationProvider, - }); - } - if (samlNameId && externalRegistrationProvider === ExternalRegistrationProviderEnum.SAML) { - userQb.andWhere('user.samlNameId = :samlNameId', { samlNameId: samlNameId }); - } - return userQb.getOne(); - }, + async findOneUserByEmail( + email: string, + externalRegistrationProvider: ExternalRegistrationProviderEnum = null, + samlNameId: string = null, + ): Promise { + const userQb = this.createQueryBuilder('user').where('user.email = :userEmail', { + userEmail: email?.toLowerCase(), + }); + if (externalRegistrationProvider) { + userQb.andWhere('user.externalRegistrationProvider = :externalRegistrationProvider', { + externalRegistrationProvider: externalRegistrationProvider, + }); + } + if (samlNameId && externalRegistrationProvider === ExternalRegistrationProviderEnum.SAML) { + userQb.andWhere('user.samlNameId = :samlNameId', { samlNameId: samlNameId }); + } + return userQb.getOne(); + }, - async findOneUserByEmailAndGroupId(email: string, groupId: string): Promise { - const userQb = this.createQueryBuilder('user') - .leftJoinAndSelect('user.groups', 'group') - .where('user.email = :userEmail', { userEmail: email?.toLowerCase() }) - .andWhere('group.id = :groupId', { groupId: groupId }); - return await userQb.getOne(); - }, + async findOneUserByEmailAndGroupId(email: string, groupId: string): Promise { + const userQb = this.createQueryBuilder('user') + .leftJoinAndSelect('user.groups', 'group') + .where('user.email = :userEmail', { userEmail: email?.toLowerCase() }) + .andWhere('group.id = :groupId', { groupId: groupId }); + return await userQb.getOne(); + }, - async findOneUserWithEmailVerification(userId: string): Promise { - const usersQb = this.createQueryBuilder('user') - .leftJoinAndSelect('user.email_verification', 'email_verification') - .where('user.id = :userId', { userId: userId }); - return await usersQb.getOne(); - }, + async findOneUserWithEmailVerification(userId: string): Promise { + const usersQb = this.createQueryBuilder('user') + .leftJoinAndSelect('user.email_verification', 'email_verification') + .where('user.id = :userId', { userId: userId }); + return await usersQb.getOne(); + }, - async findUserByEmailEndCompanyIdWithEmailVerificationAndInvitation( - email: string, - companyId: string, - ): Promise { - const usersQb = this.createQueryBuilder('user') - .leftJoinAndSelect('user.email_verification', 'email_verification') - .leftJoinAndSelect('user.user_invitation', 'user_invitation') - .leftJoinAndSelect('user.company', 'company') - .where('user.email = :userEmail', { userEmail: email?.toLowerCase() }) - .andWhere('company.id = :companyId', { companyId: companyId }); - return await usersQb.getOne(); - }, + async findUserByEmailEndCompanyIdWithEmailVerificationAndInvitation( + email: string, + companyId: string, + ): Promise { + const usersQb = this.createQueryBuilder('user') + .leftJoinAndSelect('user.email_verification', 'email_verification') + .leftJoinAndSelect('user.user_invitation', 'user_invitation') + .leftJoinAndSelect('user.company', 'company') + .where('user.email = :userEmail', { userEmail: email?.toLowerCase() }) + .andWhere('company.id = :companyId', { companyId: companyId }); + return await usersQb.getOne(); + }, - async findAllUsersInConnection(connectionId: string): Promise>> { - const usersQb = this.createQueryBuilder('user') - .leftJoinAndSelect('user.groups', 'group') - .leftJoinAndSelect('group.connection', 'connection') - .andWhere('connection.id = :connectionId', { - connectionId: connectionId, - }); - const foundUsers = await usersQb.getMany(); - return foundUsers.map((user: UserEntity) => { - delete user.connections; - delete user.groups; - return user; - }); - }, + async findAllUsersInConnection(connectionId: string): Promise>> { + const usersQb = this.createQueryBuilder('user') + .leftJoinAndSelect('user.groups', 'group') + .leftJoinAndSelect('group.connection', 'connection') + .andWhere('connection.id = :connectionId', { + connectionId: connectionId, + }); + const foundUsers = await usersQb.getMany(); + return foundUsers.map((user: UserEntity) => { + delete user.connections; + delete user.groups; + return user; + }); + }, - async saveUserEntity(user: UserEntity): Promise { - return await this.save(user); - }, + async saveUserEntity(user: UserEntity): Promise { + return await this.save(user); + }, - async deleteUserEntity(user: UserEntity): Promise { - return await this.remove(user); - }, + async deleteUserEntity(user: UserEntity): Promise { + return await this.remove(user); + }, - async getUsersWithNotNullGCLIDsInTwoWeeks(): Promise> { - const dateTwoWeeksAgo = Constants.TWO_WEEKS_AGO(); - const usersQB = this.createQueryBuilder('user') - .where('user.createdAt > :date', { date: dateTwoWeeksAgo }) - .andWhere('user.gclid IS NOT NULL') - .andWhere('user.isDemoAccount = :isDemo', { isDemo: false }); - return await usersQB.getMany(); - }, + async getUsersWithNotNullGCLIDsInTwoWeeks(): Promise> { + const dateTwoWeeksAgo = Constants.TWO_WEEKS_AGO(); + const usersQB = this.createQueryBuilder('user') + .where('user.createdAt > :date', { date: dateTwoWeeksAgo }) + .andWhere('user.gclid IS NOT NULL') + .andWhere('user.isDemoAccount = :isDemo', { isDemo: false }); + return await usersQB.getMany(); + }, - async countUsersInCompany(companyId: string): Promise { - const usersQB = this.createQueryBuilder('user') - .leftJoin('user.company', 'company') - .where('company.id = :companyId', { companyId: companyId }); - return await usersQB.getCount(); - }, + async countUsersInCompany(companyId: string): Promise { + const usersQB = this.createQueryBuilder('user') + .leftJoin('user.company', 'company') + .where('company.id = :companyId', { companyId: companyId }); + return await usersQB.getCount(); + }, - async findUsersInCompany(companyId: string, orderByRole: boolean = false): Promise> { - const usersQB = this.createQueryBuilder('user') - .leftJoin('user.company', 'company') - .where('company.id = :companyId', { companyId: companyId }) - .orderBy('user.createdAt', 'ASC'); - if (orderByRole) { - usersQB.addOrderBy('user.role', 'ASC'); - } - return await usersQB.getMany(); - }, + async findUsersInCompany(companyId: string, orderByRole: boolean = false): Promise> { + const usersQB = this.createQueryBuilder('user') + .leftJoin('user.company', 'company') + .where('company.id = :companyId', { companyId: companyId }) + .orderBy('user.createdAt', 'ASC'); + if (orderByRole) { + usersQB.addOrderBy('user.role', 'ASC'); + } + return await usersQB.getMany(); + }, - async getUserEmailOrReturnNull(userId: string): Promise { - const userQB = this.createQueryBuilder('user').where('user.id = :userId', { userId: userId }); - const user = await userQB.getOne(); - return user?.email ? user.email.toLowerCase() : null; - }, + async getUserEmailOrReturnNull(userId: string): Promise { + const userQB = this.createQueryBuilder('user').where('user.id = :userId', { userId: userId }); + const user = await userQB.getOne(); + return user?.email ? user.email.toLowerCase() : null; + }, - async getTrue(): Promise { - return !!(await this.manager.query(`SELECT (1);`)); - }, + async getTrue(): Promise { + return !!(await this.manager.query(`SELECT (1);`)); + }, - async findUserWithConnections(userId: string): Promise { - return await this.findOne({ - where: { id: userId }, - relations: ['connections'], - }); - }, + async findUserWithConnections(userId: string): Promise { + return await this.findOne({ + where: { id: userId }, + relations: ['connections'], + }); + }, - async findUsersWithoutLogs(): Promise> { - const usersQb = this.createQueryBuilder('user') - .leftJoinAndSelect('user.groups', 'group') - .leftJoinAndSelect('group.connection', 'connection') - .leftJoinAndSelect('connection.logs', 'tableLogs') - .leftJoinAndSelect('user.user_action', 'user_action') - .andWhere('user_action.mail_sent = :mail_sent', { mail_sent: false }) - .orWhere('user_action.id is null') - .andWhere('tableLogs.id is null'); - return await usersQb.getMany(); - }, + async findUsersWithoutLogs(): Promise> { + const usersQb = this.createQueryBuilder('user') + .leftJoinAndSelect('user.groups', 'group') + .leftJoinAndSelect('group.connection', 'connection') + .leftJoinAndSelect('connection.logs', 'tableLogs') + .leftJoinAndSelect('user.user_action', 'user_action') + .andWhere('user_action.mail_sent = :mail_sent', { mail_sent: false }) + .orWhere('user_action.id is null') + .andWhere('tableLogs.id is null'); + return await usersQb.getMany(); + }, - async findOneUserByGitHubId(gitHubId: number): Promise { - const userQb = this.createQueryBuilder('user') - .leftJoinAndSelect('user.github_user_identifier', 'github_user_identifier') - .where('github_user_identifier.gitHubId = :gitHubId', { gitHubId: gitHubId }); - return await userQb.getOne(); - }, + async findOneUserByGitHubId(gitHubId: number): Promise { + const userQb = this.createQueryBuilder('user') + .leftJoinAndSelect('user.github_user_identifier', 'github_user_identifier') + .where('github_user_identifier.gitHubId = :gitHubId', { gitHubId: gitHubId }); + return await userQb.getOne(); + }, - async findOneUserByEmailAndCompanyId(userEmail: string, companyId: string): Promise { - const userQb = this.createQueryBuilder('user') - .leftJoinAndSelect('user.company', 'company') - .where('user.email = :userEmail', { userEmail: userEmail?.toLowerCase() }); - if (companyId) { - userQb.andWhere('company.id = :companyId', { companyId: companyId }); - } else { - userQb.andWhere('company.id is null'); - } - return await userQb.getOne(); - }, + async findOneUserByEmailAndCompanyId(userEmail: string, companyId: string): Promise { + const userQb = this.createQueryBuilder('user') + .leftJoinAndSelect('user.company', 'company') + .where('user.email = :userEmail', { userEmail: userEmail?.toLowerCase() }); + if (companyId) { + userQb.andWhere('company.id = :companyId', { companyId: companyId }); + } else { + userQb.andWhere('company.id is null'); + } + return await userQb.getOne(); + }, - async findOneUserByIdAndCompanyId(userId: string, companyId: string): Promise { - const userQb = this.createQueryBuilder('user') - .leftJoinAndSelect('user.company', 'company') - .where('user.id = :userId', { userId: userId }) - .andWhere('company.id = :companyId', { companyId: companyId }); - return await userQb.getOne(); - }, + async findOneUserByIdAndCompanyId(userId: string, companyId: string): Promise { + const userQb = this.createQueryBuilder('user') + .leftJoinAndSelect('user.company', 'company') + .where('user.id = :userId', { userId: userId }) + .andWhere('company.id = :companyId', { companyId: companyId }); + return await userQb.getOne(); + }, - async findOneUserByIdWithCompany(userId: string): Promise { - const userQb = this.createQueryBuilder('user') - .leftJoinAndSelect('user.company', 'company') - .where('user.id = :userId', { userId: userId }); - return await userQb.getOne(); - }, + async findOneUserByIdWithCompany(userId: string): Promise { + const userQb = this.createQueryBuilder('user') + .leftJoinAndSelect('user.company', 'company') + .where('user.id = :userId', { userId: userId }); + return await userQb.getOne(); + }, - async findAllUsersWithEmail( - email: string, - externalRegistrationProvider: ExternalRegistrationProviderEnum = null, - ): Promise> { - const usersQb = this.createQueryBuilder('user') - .leftJoinAndSelect('user.company', 'company') - .where('user.email = :userEmail', { - userEmail: email?.toLowerCase(), - }); - if (externalRegistrationProvider) { - usersQb.andWhere('user.externalRegistrationProvider = :externalRegistrationProvider', { - externalRegistrationProvider: externalRegistrationProvider, - }); - } + async findAllUsersWithEmail( + email: string, + externalRegistrationProvider: ExternalRegistrationProviderEnum = null, + ): Promise> { + const usersQb = this.createQueryBuilder('user') + .leftJoinAndSelect('user.company', 'company') + .where('user.email = :userEmail', { + userEmail: email?.toLowerCase(), + }); + if (externalRegistrationProvider) { + usersQb.andWhere('user.externalRegistrationProvider = :externalRegistrationProvider', { + externalRegistrationProvider: externalRegistrationProvider, + }); + } - return await usersQb.getMany(); - }, + return await usersQb.getMany(); + }, - async findUsersByEmailsAndCompanyId(usersEmails: Array, companyId: string): Promise> { - const usersQb = this.createQueryBuilder('user') - .leftJoinAndSelect('user.company', 'company') - .where('user.email IN (:...userEmails)', { userEmails: usersEmails.map((email) => email?.toLowerCase()) }) - .andWhere('company.id = :companyId', { companyId: companyId }); - return await usersQb.getMany(); - }, + async findUsersByEmailsAndCompanyId(usersEmails: Array, companyId: string): Promise> { + const usersQb = this.createQueryBuilder('user') + .leftJoinAndSelect('user.company', 'company') + .where('user.email IN (:...userEmails)', { userEmails: usersEmails.map((email) => email?.toLowerCase()) }) + .andWhere('company.id = :companyId', { companyId: companyId }); + return await usersQb.getMany(); + }, - async suspendUsers(userIds: Array): Promise> { - const usersQb = this.createQueryBuilder('user') - .update() - .set({ suspended: true }) - .where('id IN (:...userIds)', { userIds: userIds }); - await usersQb.execute(); - return await this.createQueryBuilder('user').whereInIds(userIds).getMany(); - }, + async suspendUsers(userIds: Array): Promise> { + const usersQb = this.createQueryBuilder('user') + .update() + .set({ suspended: true }) + .where('id IN (:...userIds)', { userIds: userIds }); + await usersQb.execute(); + return await this.createQueryBuilder('user').whereInIds(userIds).getMany(); + }, - async suspendNewestUsersInCompany(companyId: string, unsuspendedUsersLeft: number = 3): Promise> { - const usersQb = this.createQueryBuilder('user') - .where('user.companyId = :companyId', { companyId: companyId }) - .orderBy('user.createdAt', 'ASC'); - const users: Array = await usersQb.getMany(); - const usersToSuspend = users.slice(unsuspendedUsersLeft); + async suspendNewestUsersInCompany(companyId: string, unsuspendedUsersLeft: number = 3): Promise> { + const usersQb = this.createQueryBuilder('user') + .where('user.companyId = :companyId', { companyId: companyId }) + .orderBy('user.createdAt', 'ASC'); + const users: Array = await usersQb.getMany(); + const usersToSuspend = users.slice(unsuspendedUsersLeft); - if (usersToSuspend.length > 0) { - await this.createQueryBuilder('user') - .update() - .set({ suspended: true }) - .where('id IN (:...userIds)', { userIds: usersToSuspend.map((user) => user.id) }) - .execute(); - } - return usersToSuspend; - }, + if (usersToSuspend.length > 0) { + await this.createQueryBuilder('user') + .update() + .set({ suspended: true }) + .where('id IN (:...userIds)', { userIds: usersToSuspend.map((user) => user.id) }) + .execute(); + } + return usersToSuspend; + }, - async unSuspendUsers(userIds: Array): Promise> { - const usersQb = this.createQueryBuilder('user') - .update() - .set({ suspended: false }) - .where('id IN (:...userIds)', { userIds: userIds }); - await usersQb.execute(); - return await this.createQueryBuilder('user').whereInIds(userIds).getMany(); - }, + async unSuspendUsers(userIds: Array): Promise> { + const usersQb = this.createQueryBuilder('user') + .update() + .set({ suspended: false }) + .where('id IN (:...userIds)', { userIds: userIds }); + await usersQb.execute(); + return await this.createQueryBuilder('user').whereInIds(userIds).getMany(); + }, - async bulkSaveUpdatedUsers(updatedUsers: Array): Promise> { - return await this.save(updatedUsers); - }, + async bulkSaveUpdatedUsers(updatedUsers: Array): Promise> { + return await this.save(updatedUsers); + }, }; diff --git a/backend/src/entities/user/repository/user.repository.interface.ts b/backend/src/entities/user/repository/user.repository.interface.ts index 996217f0a..8f0cbe0a5 100644 --- a/backend/src/entities/user/repository/user.repository.interface.ts +++ b/backend/src/entities/user/repository/user.repository.interface.ts @@ -4,66 +4,66 @@ import { ExternalRegistrationProviderEnum } from '../enums/external-registration import { UserEntity } from '../user.entity.js'; export interface IUserRepository { - createUser(userData: CreateUserDs): Promise; + createUser(userData: CreateUserDs): Promise; - findOneUserById(userId: string): Promise; + findOneUserById(userId: string): Promise; - findOneUserWithUserAction(userId: string): Promise; + findOneUserWithUserAction(userId: string): Promise; - findOneUserByEmail( - email: string, - externalRegistrationProvider?: ExternalRegistrationProviderEnum, - samlNameId?: string, - ): Promise; + findOneUserByEmail( + email: string, + externalRegistrationProvider?: ExternalRegistrationProviderEnum, + samlNameId?: string, + ): Promise; - findUserWithConnections(userId: string): Promise; + findUserWithConnections(userId: string): Promise; - findAllUsersInConnection(connectionId: string): Promise>>; + findAllUsersInConnection(connectionId: string): Promise>>; - saveRegisteringUser( - userData: RegisterUserDs, - externalRegistrationProvider?: ExternalRegistrationProviderEnum, - ): Promise; + saveRegisteringUser( + userData: RegisterUserDs, + externalRegistrationProvider?: ExternalRegistrationProviderEnum, + ): Promise; - saveUserEntity(user: UserEntity): Promise; + saveUserEntity(user: UserEntity): Promise; - findOneUserWithEmailVerification(userId: string): Promise; + findOneUserWithEmailVerification(userId: string): Promise; - findUserByEmailEndCompanyIdWithEmailVerificationAndInvitation(email: string, companyId: string): Promise; + findUserByEmailEndCompanyIdWithEmailVerificationAndInvitation(email: string, companyId: string): Promise; - deleteUserEntity(user: UserEntity): Promise; + deleteUserEntity(user: UserEntity): Promise; - getUsersWithNotNullGCLIDsInTwoWeeks(): Promise>; + getUsersWithNotNullGCLIDsInTwoWeeks(): Promise>; - getUserEmailOrReturnNull(userId: string): Promise; + getUserEmailOrReturnNull(userId: string): Promise; - getTrue(): Promise; + getTrue(): Promise; - findUsersWithoutLogs(): Promise>; + findUsersWithoutLogs(): Promise>; - findOneUserByGitHubId(gitHubId: number): Promise; + findOneUserByGitHubId(gitHubId: number): Promise; - findOneUserByEmailAndCompanyId(email: string, companyId: string): Promise; + findOneUserByEmailAndCompanyId(email: string, companyId: string): Promise; - findOneUserByIdAndCompanyId(userId: string, companyId: string): Promise; + findOneUserByIdAndCompanyId(userId: string, companyId: string): Promise; - findOneUserByIdWithCompany(userId: string): Promise; + findOneUserByIdWithCompany(userId: string): Promise; - findAllUsersWithEmail(email: string, externalProvider?: ExternalRegistrationProviderEnum): Promise>; + findAllUsersWithEmail(email: string, externalProvider?: ExternalRegistrationProviderEnum): Promise>; - findUsersByEmailsAndCompanyId(emails: Array, companyId: string): Promise>; + findUsersByEmailsAndCompanyId(emails: Array, companyId: string): Promise>; - suspendUsers(userIds: Array): Promise>; + suspendUsers(userIds: Array): Promise>; - unSuspendUsers(userIds: Array): Promise>; + unSuspendUsers(userIds: Array): Promise>; - bulkSaveUpdatedUsers(updatedUsers: Array): Promise>; + bulkSaveUpdatedUsers(updatedUsers: Array): Promise>; - findOneUserByEmailAndGroupId(email: string, groupId: string): Promise; + findOneUserByEmailAndGroupId(email: string, groupId: string): Promise; - countUsersInCompany(companyId: string): Promise; + countUsersInCompany(companyId: string): Promise; - findUsersInCompany(companyId: string, orderByRole: boolean): Promise>; + findUsersInCompany(companyId: string, orderByRole: boolean): Promise>; - suspendNewestUsersInCompany(companyId: string, unsuspendedUsersLeft: number): Promise>; + suspendNewestUsersInCompany(companyId: string, unsuspendedUsersLeft: number): Promise>; } diff --git a/backend/src/entities/user/use-cases/change-user-name-use.case.ts b/backend/src/entities/user/use-cases/change-user-name-use.case.ts index f3e71ae56..13c4a153d 100644 --- a/backend/src/entities/user/use-cases/change-user-name-use.case.ts +++ b/backend/src/entities/user/use-cases/change-user-name-use.case.ts @@ -10,28 +10,28 @@ import { IChangeUserName } from './user-use-cases.interfaces.js'; @Injectable() export class ChangeUserNameUseCase extends AbstractUseCase implements IChangeUserName { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private readonly userHelperService: UserHelperService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly userHelperService: UserHelperService, + ) { + super(); + } - protected async implementation(inputData: ChangeUserNameDS): Promise { - const { id, name } = inputData; - const foundUser = await this._dbContext.userRepository.findOneUserById(id); - if (!foundUser) { - throw new HttpException( - { - message: Messages.USER_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } + protected async implementation(inputData: ChangeUserNameDS): Promise { + const { id, name } = inputData; + const foundUser = await this._dbContext.userRepository.findOneUserById(id); + if (!foundUser) { + throw new HttpException( + { + message: Messages.USER_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } - foundUser.name = name; - const savedUser = await this._dbContext.userRepository.saveUserEntity(foundUser); - return await this.userHelperService.buildFoundUserDs(savedUser); - } + foundUser.name = name; + const savedUser = await this._dbContext.userRepository.saveUserEntity(foundUser); + return await this.userHelperService.buildFoundUserDs(savedUser); + } } diff --git a/backend/src/entities/user/use-cases/change-usual-password-use.case.ts b/backend/src/entities/user/use-cases/change-usual-password-use.case.ts index 226453bf4..22937bd84 100644 --- a/backend/src/entities/user/use-cases/change-usual-password-use.case.ts +++ b/backend/src/entities/user/use-cases/change-usual-password-use.case.ts @@ -5,37 +5,37 @@ import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; import { Encryptor } from '../../../helpers/encryption/encryptor.js'; import { - ChangeUsualUserPasswordDs, - ChangeUsualUserPasswordDto, + ChangeUsualUserPasswordDs, + ChangeUsualUserPasswordDto, } from '../application/data-structures/change-usual-user-password.ds.js'; import { generateGwtToken, IToken } from '../utils/generate-gwt-token.js'; -import { IUsualPasswordChange } from './user-use-cases.interfaces.js'; import { get2FaScope } from '../utils/is-jwt-scope-need.util.js'; +import { IUsualPasswordChange } from './user-use-cases.interfaces.js'; @Injectable() export class ChangeUsualPasswordUseCase - extends AbstractUseCase - implements IUsualPasswordChange + extends AbstractUseCase + implements IUsualPasswordChange { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } - protected async implementation(userData: ChangeUsualUserPasswordDs): Promise { - const user = await this._dbContext.userRepository.findOneUserById(userData.userId); - if (!user) { - throw new NotFoundException(Messages.USER_NOT_FOUND); - } - const oldPasswordValidationResult = await Encryptor.verifyUserPassword(userData.oldPassword, user.password); - if (!oldPasswordValidationResult) { - throw new BadRequestException(Messages.PASSWORD_OLD_INVALID); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } + protected async implementation(userData: ChangeUsualUserPasswordDs): Promise { + const user = await this._dbContext.userRepository.findOneUserById(userData.userId); + if (!user) { + throw new NotFoundException(Messages.USER_NOT_FOUND); + } + const oldPasswordValidationResult = await Encryptor.verifyUserPassword(userData.oldPassword, user.password); + if (!oldPasswordValidationResult) { + throw new BadRequestException(Messages.PASSWORD_OLD_INVALID); + } - user.password = await Encryptor.hashUserPassword(userData.newPassword); - const updatedUser = await this._dbContext.userRepository.saveUserEntity(user); - const foundUserCompany = await this._dbContext.companyInfoRepository.finOneCompanyInfoByUserId(updatedUser.id); - return generateGwtToken(updatedUser, get2FaScope(updatedUser, foundUserCompany)); - } + user.password = await Encryptor.hashUserPassword(userData.newPassword); + const updatedUser = await this._dbContext.userRepository.saveUserEntity(user); + const foundUserCompany = await this._dbContext.companyInfoRepository.finOneCompanyInfoByUserId(updatedUser.id); + return generateGwtToken(updatedUser, get2FaScope(updatedUser, foundUserCompany)); + } } diff --git a/backend/src/entities/user/use-cases/delete-user-account-use-case.ts b/backend/src/entities/user/use-cases/delete-user-account-use-case.ts index da51888a0..d06affa41 100644 --- a/backend/src/entities/user/use-cases/delete-user-account-use-case.ts +++ b/backend/src/entities/user/use-cases/delete-user-account-use-case.ts @@ -3,67 +3,67 @@ import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { isSaaS } from '../../../helpers/app/is-saas.js'; +import { SaasCompanyGatewayService } from '../../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; import { RegisteredUserDs } from '../application/data-structures/registered-user.ds.js'; import { IDeleteUserAccount } from './user-use-cases.interfaces.js'; -import { SaasCompanyGatewayService } from '../../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; -import { isSaaS } from '../../../helpers/app/is-saas.js'; @Injectable({ scope: Scope.REQUEST }) export class DeleteUserAccountUseCase - extends AbstractUseCase> - implements IDeleteUserAccount + extends AbstractUseCase> + implements IDeleteUserAccount { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private readonly saasCompanyGatewayService: SaasCompanyGatewayService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly saasCompanyGatewayService: SaasCompanyGatewayService, + ) { + super(); + } - protected async implementation(userId: string): Promise> { - const foundUser = await this._dbContext.userRepository.findOneUserById(userId); - if (!foundUser) { - throw new HttpException( - { - message: Messages.USER_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } + protected async implementation(userId: string): Promise> { + const foundUser = await this._dbContext.userRepository.findOneUserById(userId); + if (!foundUser) { + throw new HttpException( + { + message: Messages.USER_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } - const userCompanyId = foundUser.company.id; + const userCompanyId = foundUser.company.id; - const usersCountInCompany = await this._dbContext.userRepository.countUsersInCompany(userCompanyId); + const usersCountInCompany = await this._dbContext.userRepository.countUsersInCompany(userCompanyId); - if (usersCountInCompany <= 1) { - const foundFullCompany = await this._dbContext.companyInfoRepository.findFullCompanyInfoByUserId(userId); - const { users, connections, invitations, id } = foundFullCompany; - if (isSaaS()) { - const deleteResult = await this.saasCompanyGatewayService.deleteCompany(id); - if (!deleteResult) { - throw new InternalServerErrorException(Messages.SAAS_DELETE_COMPANY_FAILED_UNHANDLED_ERROR); - } - } - if (users.length) { - await this._dbContext.userRepository.remove(users); - } - if (connections.length) { - await this._dbContext.connectionRepository.remove(connections); - } - if (invitations.length) { - await this._dbContext.invitationInCompanyRepository.remove(invitations); - } - await this._dbContext.companyInfoRepository.remove(foundFullCompany); - } else { - await this._dbContext.userRepository.deleteUserEntity(foundUser); - } + if (usersCountInCompany <= 1) { + const foundFullCompany = await this._dbContext.companyInfoRepository.findFullCompanyInfoByUserId(userId); + const { users, connections, invitations, id } = foundFullCompany; + if (isSaaS()) { + const deleteResult = await this.saasCompanyGatewayService.deleteCompany(id); + if (!deleteResult) { + throw new InternalServerErrorException(Messages.SAAS_DELETE_COMPANY_FAILED_UNHANDLED_ERROR); + } + } + if (users.length) { + await this._dbContext.userRepository.remove(users); + } + if (connections.length) { + await this._dbContext.connectionRepository.remove(connections); + } + if (invitations.length) { + await this._dbContext.invitationInCompanyRepository.remove(invitations); + } + await this._dbContext.companyInfoRepository.remove(foundFullCompany); + } else { + await this._dbContext.userRepository.deleteUserEntity(foundUser); + } - return { - id: foundUser.id, - email: foundUser.email, - name: foundUser.name, - externalRegistrationProvider: foundUser.externalRegistrationProvider, - }; - } + return { + id: foundUser.id, + email: foundUser.email, + name: foundUser.name, + externalRegistrationProvider: foundUser.externalRegistrationProvider, + }; + } } diff --git a/backend/src/entities/user/use-cases/disable-otp.use.case.ts b/backend/src/entities/user/use-cases/disable-otp.use.case.ts index afb33dd5e..f08e1b58d 100644 --- a/backend/src/entities/user/use-cases/disable-otp.use.case.ts +++ b/backend/src/entities/user/use-cases/disable-otp.use.case.ts @@ -1,10 +1,10 @@ import { - Injectable, - Inject, - NotFoundException, - ForbiddenException, - BadRequestException, - InternalServerErrorException, + BadRequestException, + ForbiddenException, + Inject, + Injectable, + InternalServerErrorException, + NotFoundException, } from '@nestjs/common'; import { authenticator } from 'otplib'; import AbstractUseCase from '../../../common/abstract-use.case.js'; @@ -17,42 +17,42 @@ import { IDisableOTP } from './user-use-cases.interfaces.js'; @Injectable() export class DisableOtpUseCase extends AbstractUseCase implements IDisableOTP { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: VerifyOtpDS): Promise { - const { userId, otpToken } = inputData; - const foundUser = await this._dbContext.userRepository.findOneUserById(userId); - if (!foundUser) { - throw new NotFoundException(Messages.USER_NOT_FOUND); - } + protected async implementation(inputData: VerifyOtpDS): Promise { + const { userId, otpToken } = inputData; + const foundUser = await this._dbContext.userRepository.findOneUserById(userId); + if (!foundUser) { + throw new NotFoundException(Messages.USER_NOT_FOUND); + } - const foundUserCompany = await this._dbContext.companyInfoRepository.finOneCompanyInfoByUserId(userId); - if (foundUserCompany.is2faEnabled) { - throw new ForbiddenException(Messages.DISABLING_2FA_FORBIDDEN_BY_ADMIN); - } + const foundUserCompany = await this._dbContext.companyInfoRepository.finOneCompanyInfoByUserId(userId); + if (foundUserCompany.is2faEnabled) { + throw new ForbiddenException(Messages.DISABLING_2FA_FORBIDDEN_BY_ADMIN); + } - const { otpSecretKey } = foundUser; - if (!otpSecretKey) { - throw new BadRequestException(Messages.OTP_NOT_ENABLED); - } - try { - const isValid = authenticator.check(otpToken, otpSecretKey); - if (isValid) { - foundUser.isOTPEnabled = false; - foundUser.otpSecretKey = null; - await this._dbContext.userRepository.saveUserEntity(foundUser); - return { - disabled: true, - }; - } - } catch (_error) { - throw new BadRequestException(Messages.OTP_DISABLING_FAILED_INVALID_TOKEN); - } - throw new InternalServerErrorException(Messages.OTP_DISABLING_FAILED); - } + const { otpSecretKey } = foundUser; + if (!otpSecretKey) { + throw new BadRequestException(Messages.OTP_NOT_ENABLED); + } + try { + const isValid = authenticator.check(otpToken, otpSecretKey); + if (isValid) { + foundUser.isOTPEnabled = false; + foundUser.otpSecretKey = null; + await this._dbContext.userRepository.saveUserEntity(foundUser); + return { + disabled: true, + }; + } + } catch (_error) { + throw new BadRequestException(Messages.OTP_DISABLING_FAILED_INVALID_TOKEN); + } + throw new InternalServerErrorException(Messages.OTP_DISABLING_FAILED); + } } diff --git a/backend/src/entities/user/use-cases/find-user-use.case.ts b/backend/src/entities/user/use-cases/find-user-use.case.ts index c6a0d9030..a27afe93d 100644 --- a/backend/src/entities/user/use-cases/find-user-use.case.ts +++ b/backend/src/entities/user/use-cases/find-user-use.case.ts @@ -2,32 +2,33 @@ import { Inject, Injectable, NotFoundException } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; +import { Messages } from '../../../exceptions/text/messages.js'; import { AmplitudeService } from '../../amplitude/amplitude.service.js'; import { CreateUserDs } from '../application/data-structures/create-user.ds.js'; import { FindUserDs } from '../application/data-structures/find-user.ds.js'; import { FoundUserDto } from '../dto/found-user.dto.js'; import { UserHelperService } from '../user-helper.service.js'; import { IFindUserUseCase } from './user-use-cases.interfaces.js'; -import { Messages } from '../../../exceptions/text/messages.js'; @Injectable() export class FindUserUseCase - extends AbstractUseCase - implements IFindUserUseCase + extends AbstractUseCase + implements IFindUserUseCase { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext,readonly _amplitudeService: AmplitudeService, - private readonly userHelperService: UserHelperService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + readonly _amplitudeService: AmplitudeService, + private readonly userHelperService: UserHelperService, + ) { + super(); + } - protected async implementation(userData: FindUserDs | CreateUserDs): Promise { - const user = await this._dbContext.userRepository.findOneUserById(userData.id); - if (user) { - return await this.userHelperService.buildFoundUserDs(user); - } - throw new NotFoundException(Messages.USER_NOT_FOUND); - } + protected async implementation(userData: FindUserDs | CreateUserDs): Promise { + const user = await this._dbContext.userRepository.findOneUserById(userData.id); + if (user) { + return await this.userHelperService.buildFoundUserDs(user); + } + throw new NotFoundException(Messages.USER_NOT_FOUND); + } } diff --git a/backend/src/entities/user/use-cases/generate-otp-use.case.ts b/backend/src/entities/user/use-cases/generate-otp-use.case.ts index 9c00b7d6a..3b079c8cd 100644 --- a/backend/src/entities/user/use-cases/generate-otp-use.case.ts +++ b/backend/src/entities/user/use-cases/generate-otp-use.case.ts @@ -1,49 +1,49 @@ -import { Injectable, Inject, HttpException, HttpStatus } from '@nestjs/common'; +import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; +import { authenticator } from 'otplib'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import { IGenerateOTP } from './user-use-cases.interfaces.js'; import { Messages } from '../../../exceptions/text/messages.js'; -import { authenticator } from 'otplib'; import { OtpSecretDS } from '../application/data-structures/otp-secret.ds.js'; import { generateQRCode } from '../utils/generate-qr-code.js'; +import { IGenerateOTP } from './user-use-cases.interfaces.js'; @Injectable() export class GenerateOtpUseCase extends AbstractUseCase implements IGenerateOTP { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(userId: string): Promise { - const foundUser = await this._dbContext.userRepository.findOneUserById(userId); - if (!foundUser) { - throw new HttpException( - { - message: Messages.USER_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } + protected async implementation(userId: string): Promise { + const foundUser = await this._dbContext.userRepository.findOneUserById(userId); + if (!foundUser) { + throw new HttpException( + { + message: Messages.USER_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } - if (!foundUser.isActive) { - throw new HttpException( - { - message: Messages.USER_NOT_ACTIVE, - }, - HttpStatus.BAD_REQUEST, - ); - } + if (!foundUser.isActive) { + throw new HttpException( + { + message: Messages.USER_NOT_ACTIVE, + }, + HttpStatus.BAD_REQUEST, + ); + } - const otpSecretKey = authenticator.generateSecret(); - foundUser.otpSecretKey = otpSecretKey; - await this._dbContext.userRepository.saveUserEntity(foundUser); - const { otpauth, qrCode } = await generateQRCode(foundUser.email, otpSecretKey); - return { - otpauth_url: otpauth, - qrCode: qrCode, - }; - } + const otpSecretKey = authenticator.generateSecret(); + foundUser.otpSecretKey = otpSecretKey; + await this._dbContext.userRepository.saveUserEntity(foundUser); + const { otpauth, qrCode } = await generateQRCode(foundUser.email, otpSecretKey); + return { + otpauth_url: otpauth, + qrCode: qrCode, + }; + } } diff --git a/backend/src/entities/user/use-cases/get-user-session-settings.use.case.ts b/backend/src/entities/user/use-cases/get-user-session-settings.use.case.ts index b2aa76012..6d2c34eff 100644 --- a/backend/src/entities/user/use-cases/get-user-session-settings.use.case.ts +++ b/backend/src/entities/user/use-cases/get-user-session-settings.use.case.ts @@ -6,21 +6,21 @@ import { SaveUserSettingsDs } from '../application/data-structures/save-user-set import { IGetUserSettings } from './user-use-cases.interfaces.js'; export class GetUserSessionSettingsUseCase - extends AbstractUseCase - implements IGetUserSettings + extends AbstractUseCase + implements IGetUserSettings { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(userId: string): Promise { - const result = await this._dbContext.userSessionSettingsRepository.getUserSettingsByUserId(userId); - return { - userId: userId, - userSettings: result?.userSettings ? result.userSettings : null, - }; - } + protected async implementation(userId: string): Promise { + const result = await this._dbContext.userSessionSettingsRepository.getUserSettingsByUserId(userId); + return { + userId: userId, + userSettings: result?.userSettings ? result.userSettings : null, + }; + } } diff --git a/backend/src/entities/user/use-cases/log-out.use.case.ts b/backend/src/entities/user/use-cases/log-out.use.case.ts index 8ead8ee25..c29d04926 100644 --- a/backend/src/entities/user/use-cases/log-out.use.case.ts +++ b/backend/src/entities/user/use-cases/log-out.use.case.ts @@ -7,24 +7,24 @@ import { ILogOut } from './user-use-cases.interfaces.js'; @Injectable() export class LogOutUseCase extends AbstractUseCase implements ILogOut { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(token: string): Promise { - try { - await this._dbContext.logOutRepository.saveLogOutUserToken(token); - return true; - } catch (e) { - throw new HttpException( - { - message: Messages.FAILED_LOGOUT + ' Error: ' + e.message, - }, - HttpStatus.INTERNAL_SERVER_ERROR, - ); - } - } + protected async implementation(token: string): Promise { + try { + await this._dbContext.logOutRepository.saveLogOutUserToken(token); + return true; + } catch (e) { + throw new HttpException( + { + message: Messages.FAILED_LOGOUT + ' Error: ' + e.message, + }, + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } } diff --git a/backend/src/entities/user/use-cases/otp-login-use.case.ts b/backend/src/entities/user/use-cases/otp-login-use.case.ts index 15f7e29c9..45acfc358 100644 --- a/backend/src/entities/user/use-cases/otp-login-use.case.ts +++ b/backend/src/entities/user/use-cases/otp-login-use.case.ts @@ -1,72 +1,72 @@ import { BadRequestException, Inject, Injectable, NotFoundException } from '@nestjs/common'; +import { authenticator } from 'otplib'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import { IOtpLogin } from './user-use-cases.interfaces.js'; -import { IToken, generateGwtToken } from '../utils/generate-gwt-token.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { SignInMethodEnum } from '../../user-sign-in-audit/enums/sign-in-method.enum.js'; +import { SignInStatusEnum } from '../../user-sign-in-audit/enums/sign-in-status.enum.js'; +import { SignInAuditService } from '../../user-sign-in-audit/sign-in-audit.service.js'; import { VerifyOtpDS } from '../application/data-structures/verify-otp.ds.js'; -import { authenticator } from 'otplib'; +import { generateGwtToken, IToken } from '../utils/generate-gwt-token.js'; import { get2FaScope } from '../utils/is-jwt-scope-need.util.js'; -import { SignInAuditService } from '../../user-sign-in-audit/sign-in-audit.service.js'; -import { SignInStatusEnum } from '../../user-sign-in-audit/enums/sign-in-status.enum.js'; -import { SignInMethodEnum } from '../../user-sign-in-audit/enums/sign-in-method.enum.js'; +import { IOtpLogin } from './user-use-cases.interfaces.js'; @Injectable() export class OtpLoginUseCase extends AbstractUseCase implements IOtpLogin { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private readonly signInAuditService: SignInAuditService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly signInAuditService: SignInAuditService, + ) { + super(); + } - protected async implementation(inputData: VerifyOtpDS): Promise { - const { userId, otpToken, ipAddress, userAgent } = inputData; - const foundUser = await this._dbContext.userRepository.findOneUserById(userId); - if (!foundUser) { - throw new NotFoundException(Messages.USER_NOT_FOUND); - } - const isValid = authenticator.check(otpToken, foundUser.otpSecretKey); - if (!isValid) { - await this.recordSignInAudit( - foundUser.email, - userId, - SignInStatusEnum.FAILED, - ipAddress, - userAgent, - Messages.LOGIN_DENIED_INVALID_OTP, - ); - throw new BadRequestException(Messages.LOGIN_DENIED_INVALID_OTP); - } + protected async implementation(inputData: VerifyOtpDS): Promise { + const { userId, otpToken, ipAddress, userAgent } = inputData; + const foundUser = await this._dbContext.userRepository.findOneUserById(userId); + if (!foundUser) { + throw new NotFoundException(Messages.USER_NOT_FOUND); + } + const isValid = authenticator.check(otpToken, foundUser.otpSecretKey); + if (!isValid) { + await this.recordSignInAudit( + foundUser.email, + userId, + SignInStatusEnum.FAILED, + ipAddress, + userAgent, + Messages.LOGIN_DENIED_INVALID_OTP, + ); + throw new BadRequestException(Messages.LOGIN_DENIED_INVALID_OTP); + } - await this.recordSignInAudit(foundUser.email, userId, SignInStatusEnum.SUCCESS, ipAddress, userAgent); + await this.recordSignInAudit(foundUser.email, userId, SignInStatusEnum.SUCCESS, ipAddress, userAgent); - const foundUserCompany = await this._dbContext.companyInfoRepository.finOneCompanyInfoByUserId(foundUser.id); - return generateGwtToken(foundUser, get2FaScope(foundUser, foundUserCompany)); - } + const foundUserCompany = await this._dbContext.companyInfoRepository.finOneCompanyInfoByUserId(foundUser.id); + return generateGwtToken(foundUser, get2FaScope(foundUser, foundUserCompany)); + } - private async recordSignInAudit( - email: string, - userId: string | null, - status: SignInStatusEnum, - ipAddress: string, - userAgent: string, - failureReason?: string, - ): Promise { - try { - await this.signInAuditService.createSignInAuditRecord({ - email, - userId, - status, - signInMethod: SignInMethodEnum.OTP, - ipAddress, - userAgent, - failureReason, - }); - } catch (e) { - console.error('Failed to record sign-in audit:', e); - } - } + private async recordSignInAudit( + email: string, + userId: string | null, + status: SignInStatusEnum, + ipAddress: string, + userAgent: string, + failureReason?: string, + ): Promise { + try { + await this.signInAuditService.createSignInAuditRecord({ + email, + userId, + status, + signInMethod: SignInMethodEnum.OTP, + ipAddress, + userAgent, + failureReason, + }); + } catch (e) { + console.error('Failed to record sign-in audit:', e); + } + } } diff --git a/backend/src/entities/user/use-cases/request-change-user-email.use.case.ts b/backend/src/entities/user/use-cases/request-change-user-email.use.case.ts index 05dd830e9..3269b31d0 100644 --- a/backend/src/entities/user/use-cases/request-change-user-email.use.case.ts +++ b/backend/src/entities/user/use-cases/request-change-user-email.use.case.ts @@ -3,10 +3,10 @@ import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; -import { OperationResultMessageDs } from '../application/data-structures/operation-result-message.ds.js'; -import { IRequestEmailChange } from './user-use-cases.interfaces.js'; import { SaasCompanyGatewayService } from '../../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; import { EmailService } from '../../email/email/email.service.js'; +import { OperationResultMessageDs } from '../application/data-structures/operation-result-message.ds.js'; +import { IRequestEmailChange } from './user-use-cases.interfaces.js'; @Injectable() export class RequestChangeUserEmailUseCase diff --git a/backend/src/entities/user/use-cases/request-email-verification.use.case.ts b/backend/src/entities/user/use-cases/request-email-verification.use.case.ts index 0998f652a..a089be47f 100644 --- a/backend/src/entities/user/use-cases/request-email-verification.use.case.ts +++ b/backend/src/entities/user/use-cases/request-email-verification.use.case.ts @@ -3,10 +3,10 @@ import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; -import { OperationResultMessageDs } from '../application/data-structures/operation-result-message.ds.js'; -import { IRequestEmailVerification } from './user-use-cases.interfaces.js'; import { SaasCompanyGatewayService } from '../../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; import { EmailService } from '../../email/email/email.service.js'; +import { OperationResultMessageDs } from '../application/data-structures/operation-result-message.ds.js'; +import { IRequestEmailVerification } from './user-use-cases.interfaces.js'; @Injectable() export class RequestEmailVerificationUseCase diff --git a/backend/src/entities/user/use-cases/request-reset-user-password.use.case.ts b/backend/src/entities/user/use-cases/request-reset-user-password.use.case.ts index 9ed84e0f3..a6b077acd 100644 --- a/backend/src/entities/user/use-cases/request-reset-user-password.use.case.ts +++ b/backend/src/entities/user/use-cases/request-reset-user-password.use.case.ts @@ -4,10 +4,10 @@ import { IGlobalDatabaseContext } from '../../../common/application/global-datab import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; import { SaasCompanyGatewayService } from '../../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; +import { EmailService } from '../../email/email/email.service.js'; import { OperationResultMessageDs } from '../application/data-structures/operation-result-message.ds.js'; import { RequestRestUserPasswordDto } from '../dto/request-rest-user-password.dto.js'; import { IRequestPasswordReset } from './user-use-cases.interfaces.js'; -import { EmailService } from '../../email/email/email.service.js'; export class RequestResetUserPasswordUseCase extends AbstractUseCase diff --git a/backend/src/entities/user/use-cases/save-user-session-settings.use.case.ts b/backend/src/entities/user/use-cases/save-user-session-settings.use.case.ts index 3dc1de67e..25f412043 100644 --- a/backend/src/entities/user/use-cases/save-user-session-settings.use.case.ts +++ b/backend/src/entities/user/use-cases/save-user-session-settings.use.case.ts @@ -6,22 +6,22 @@ import { SaveUserSettingsDs } from '../application/data-structures/save-user-set import { ISaveUserSettings } from './user-use-cases.interfaces.js'; export class SaveUserSettingsUseCase - extends AbstractUseCase - implements ISaveUserSettings + extends AbstractUseCase + implements ISaveUserSettings { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: SaveUserSettingsDs): Promise { - const { userId, userSettings } = inputData; - const result = await this._dbContext.userSessionSettingsRepository.createOrUpdateUserSettings(userId, userSettings); - return { - userId: result.userId, - userSettings: result.userSettings, - }; - } + protected async implementation(inputData: SaveUserSettingsDs): Promise { + const { userId, userSettings } = inputData; + const result = await this._dbContext.userSessionSettingsRepository.createOrUpdateUserSettings(userId, userSettings); + return { + userId: result.userId, + userSettings: result.userSettings, + }; + } } diff --git a/backend/src/entities/user/use-cases/toggle-test-connections-display-mode.use.case.ts b/backend/src/entities/user/use-cases/toggle-test-connections-display-mode.use.case.ts index 2747a5b0d..37cc8e715 100644 --- a/backend/src/entities/user/use-cases/toggle-test-connections-display-mode.use.case.ts +++ b/backend/src/entities/user/use-cases/toggle-test-connections-display-mode.use.case.ts @@ -1,32 +1,32 @@ import { Inject, Injectable, NotFoundException, Scope } from '@nestjs/common'; +import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; -import { IToggleTestConnectionsMode } from './user-use-cases.interfaces.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { SuccessResponse } from '../../../microservices/saas-microservice/data-structures/common-responce.ds.js'; import { ToggleConnectionDisplayModeDs } from '../application/data-structures/toggle-connection-display-mode.ds.js'; +import { IToggleTestConnectionsMode } from './user-use-cases.interfaces.js'; @Injectable({ scope: Scope.REQUEST }) export class ToggleTestConnectionsDisplayModeUseCase - extends AbstractUseCase - implements IToggleTestConnectionsMode + extends AbstractUseCase + implements IToggleTestConnectionsMode { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - public async implementation(inputData: ToggleConnectionDisplayModeDs): Promise { - const { userId, displayMode } = inputData; - const user = await this._dbContext.userRepository.findOneUserById(userId); - if (!user) { - throw new NotFoundException(Messages.USER_NOT_FOUND); - } - user.showTestConnections = displayMode; - await this._dbContext.userRepository.save(user); - return { success: true }; - } + public async implementation(inputData: ToggleConnectionDisplayModeDs): Promise { + const { userId, displayMode } = inputData; + const user = await this._dbContext.userRepository.findOneUserById(userId); + if (!user) { + throw new NotFoundException(Messages.USER_NOT_FOUND); + } + user.showTestConnections = displayMode; + await this._dbContext.userRepository.save(user); + return { success: true }; + } } diff --git a/backend/src/entities/user/use-cases/user-use-cases.interfaces.ts b/backend/src/entities/user/use-cases/user-use-cases.interfaces.ts index 9f6d2bf26..9844e4d53 100644 --- a/backend/src/entities/user/use-cases/user-use-cases.interfaces.ts +++ b/backend/src/entities/user/use-cases/user-use-cases.interfaces.ts @@ -8,8 +8,8 @@ import { FindUserDs } from '../application/data-structures/find-user.ds.js'; import { OperationResultMessageDs } from '../application/data-structures/operation-result-message.ds.js'; import { OtpSecretDS } from '../application/data-structures/otp-secret.ds.js'; import { - OtpDisablingResultDS, - OtpValidationResultDS, + OtpDisablingResultDS, + OtpValidationResultDS, } from '../application/data-structures/otp-validation-result.ds.js'; import { RegisteredUserDs } from '../application/data-structures/registered-user.ds.js'; import { ResetUsualUserPasswordDs } from '../application/data-structures/reset-usual-user-password.ds.js'; @@ -22,77 +22,77 @@ import { RequestRestUserPasswordDto } from '../dto/request-rest-user-password.dt import { IToken } from '../utils/generate-gwt-token.js'; export interface IFindUserUseCase { - execute(userData: FindUserDs | CreateUserDs, inTransaction: InTransactionEnum): Promise; + execute(userData: FindUserDs | CreateUserDs, inTransaction: InTransactionEnum): Promise; } export interface IUsualLogin { - execute(userData: UsualLoginDs, inTransaction: InTransactionEnum): Promise; + execute(userData: UsualLoginDs, inTransaction: InTransactionEnum): Promise; } export interface IOtpLogin { - execute(inputData: VerifyOtpDS, inTransaction: InTransactionEnum): Promise; + execute(inputData: VerifyOtpDS, inTransaction: InTransactionEnum): Promise; } export interface ILogOut { - execute(token: string, inTransaction: InTransactionEnum): Promise; + execute(token: string, inTransaction: InTransactionEnum): Promise; } export interface IUsualPasswordChange { - execute(inputData: ChangeUsualUserPasswordDto, inTransaction: InTransactionEnum): Promise; + execute(inputData: ChangeUsualUserPasswordDto, inTransaction: InTransactionEnum): Promise; } export interface IVerifyEmail { - execute(verificationString: string, inTransaction: InTransactionEnum): Promise; + execute(verificationString: string, inTransaction: InTransactionEnum): Promise; } export interface IVerifyPasswordReset { - execute(inputData: ResetUsualUserPasswordDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: ResetUsualUserPasswordDs, inTransaction: InTransactionEnum): Promise; } export interface IRequestPasswordReset { - execute(emailData: RequestRestUserPasswordDto, inTransaction: InTransactionEnum): Promise; + execute(emailData: RequestRestUserPasswordDto, inTransaction: InTransactionEnum): Promise; } export interface IRequestEmailChange { - execute(userId: string, inTransaction: InTransactionEnum): Promise; + execute(userId: string, inTransaction: InTransactionEnum): Promise; } export interface IVerifyEmailChange { - execute(inputData: ChangeUserEmailDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: ChangeUserEmailDs, inTransaction: InTransactionEnum): Promise; } export interface IRequestEmailVerification { - execute(userId: string, inTransaction: InTransactionEnum): Promise; + execute(userId: string, inTransaction: InTransactionEnum): Promise; } export interface IDeleteUserAccount { - execute(userId: string, inTransaction: InTransactionEnum): Promise>; + execute(userId: string, inTransaction: InTransactionEnum): Promise>; } export interface IChangeUserName { - execute(inputData: ChangeUserNameDS, inTransaction: InTransactionEnum): Promise; + execute(inputData: ChangeUserNameDS, inTransaction: InTransactionEnum): Promise; } export interface IGenerateOTP { - execute(userId: string, inTransaction: InTransactionEnum): Promise; + execute(userId: string, inTransaction: InTransactionEnum): Promise; } export interface IVerifyOTP { - execute(inputData: VerifyOtpDS, inTransaction: InTransactionEnum): Promise; + execute(inputData: VerifyOtpDS, inTransaction: InTransactionEnum): Promise; } export interface IDisableOTP { - execute(inputData: VerifyOtpDS, inTransaction: InTransactionEnum): Promise; + execute(inputData: VerifyOtpDS, inTransaction: InTransactionEnum): Promise; } export interface ISaveUserSettings { - execute(settingsData: SaveUserSettingsDs, inTransaction: InTransactionEnum): Promise; + execute(settingsData: SaveUserSettingsDs, inTransaction: InTransactionEnum): Promise; } export interface IGetUserSettings { - execute(userId: string, inTransaction: InTransactionEnum): Promise; + execute(userId: string, inTransaction: InTransactionEnum): Promise; } export interface IToggleTestConnectionsMode { - execute(inputData: ToggleConnectionDisplayModeDs, inTransaction: InTransactionEnum): Promise; + execute(inputData: ToggleConnectionDisplayModeDs, inTransaction: InTransactionEnum): Promise; } diff --git a/backend/src/entities/user/use-cases/usual-login-use.case.ts b/backend/src/entities/user/use-cases/usual-login-use.case.ts index 35bfbf879..232e2ac48 100644 --- a/backend/src/entities/user/use-cases/usual-login-use.case.ts +++ b/backend/src/entities/user/use-cases/usual-login-use.case.ts @@ -3,179 +3,179 @@ import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { isSaaS } from '../../../helpers/app/is-saas.js'; +import { isTest } from '../../../helpers/app/is-test.js'; +import { Constants } from '../../../helpers/constants/constants.js'; import { Encryptor } from '../../../helpers/encryption/encryptor.js'; +import { ValidationHelper } from '../../../helpers/validators/validation-helper.js'; +import { SaasCompanyGatewayService } from '../../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; +import { SignInMethodEnum } from '../../user-sign-in-audit/enums/sign-in-method.enum.js'; +import { SignInStatusEnum } from '../../user-sign-in-audit/enums/sign-in-status.enum.js'; +import { SignInAuditService } from '../../user-sign-in-audit/sign-in-audit.service.js'; import { UsualLoginDs } from '../application/data-structures/usual-login.ds.js'; -import { generateGwtToken, generateTemporaryJwtToken, IToken } from '../utils/generate-gwt-token.js'; -import { IUsualLogin } from './user-use-cases.interfaces.js'; import { UserEntity } from '../user.entity.js'; +import { generateGwtToken, generateTemporaryJwtToken, IToken } from '../utils/generate-gwt-token.js'; import { get2FaScope } from '../utils/is-jwt-scope-need.util.js'; -import { SaasCompanyGatewayService } from '../../../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; -import { isTest } from '../../../helpers/app/is-test.js'; -import { isSaaS } from '../../../helpers/app/is-saas.js'; -import { ValidationHelper } from '../../../helpers/validators/validation-helper.js'; -import { Constants } from '../../../helpers/constants/constants.js'; -import { SignInAuditService } from '../../user-sign-in-audit/sign-in-audit.service.js'; -import { SignInStatusEnum } from '../../user-sign-in-audit/enums/sign-in-status.enum.js'; -import { SignInMethodEnum } from '../../user-sign-in-audit/enums/sign-in-method.enum.js'; +import { IUsualLogin } from './user-use-cases.interfaces.js'; @Injectable() export class UsualLoginUseCase extends AbstractUseCase implements IUsualLogin { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private readonly saasCompanyGatewayService: SaasCompanyGatewayService, - private readonly signInAuditService: SignInAuditService, - ) { - super(); - } - - protected async implementation(userData: UsualLoginDs): Promise { - const { request_domain, ipAddress, userAgent } = userData; - let { companyId } = userData; - const email = userData.email.toLowerCase(); - let user: UserEntity = null; - - if (companyId) { - user = await this._dbContext.userRepository.findOneUserByEmailAndCompanyId(email, companyId); - if (!user) { - await this.recordSignInAudit( - email, - null, - SignInStatusEnum.FAILED, - ipAddress, - userAgent, - Messages.USER_NOT_FOUND, - ); - throw new NotFoundException(Messages.USER_NOT_FOUND); - } - } else if (!Constants.APP_REQUEST_DOMAINS().includes(request_domain) && isSaaS()) { - const foundUserCompanyIdByDomain = - await this.saasCompanyGatewayService.getCompanyIdByCustomDomain(request_domain); - const foundUser = await this._dbContext.userRepository.findOneUserByEmailAndCompanyId( - email, - foundUserCompanyIdByDomain, - ); - if (!foundUser) { - await this.recordSignInAudit( - email, - null, - SignInStatusEnum.FAILED, - ipAddress, - userAgent, - Messages.USER_NOT_FOUND_FOR_THIS_DOMAIN, - ); - throw new BadRequestException(Messages.USER_NOT_FOUND_FOR_THIS_DOMAIN); - } - user = foundUser; - companyId = foundUser.company.id; - } else { - const foundUsers = await this._dbContext.userRepository.findAllUsersWithEmail(email); - if (foundUsers.length > 1) { - await this.recordSignInAudit( - email, - null, - SignInStatusEnum.FAILED, - ipAddress, - userAgent, - Messages.LOGIN_DENIED_SHOULD_CHOOSE_COMPANY, - ); - throw new BadRequestException(Messages.LOGIN_DENIED_SHOULD_CHOOSE_COMPANY); - } - user = foundUsers[0]; - companyId = foundUsers[0]?.company?.id; - } - - if (!user) { - await this.recordSignInAudit(email, null, SignInStatusEnum.FAILED, ipAddress, userAgent, Messages.USER_NOT_FOUND); - throw new NotFoundException(Messages.USER_NOT_FOUND); - } - if (!userData.password) { - await this.recordSignInAudit( - email, - user.id, - SignInStatusEnum.FAILED, - ipAddress, - userAgent, - Messages.PASSWORD_MISSING, - ); - throw new BadRequestException(Messages.PASSWORD_MISSING); - } - - await this.validateRequestDomain(request_domain, companyId); - - const passwordValidationResult = await Encryptor.verifyUserPassword(userData.password, user.password); - if (!passwordValidationResult) { - await this.recordSignInAudit( - email, - user.id, - SignInStatusEnum.FAILED, - ipAddress, - userAgent, - Messages.LOGIN_DENIED, - ); - throw new BadRequestException(Messages.LOGIN_DENIED); - } - if (user.isOTPEnabled) { - return generateTemporaryJwtToken(user); - } - - await this.recordSignInAudit(email, user.id, SignInStatusEnum.SUCCESS, ipAddress, userAgent); - - const foundUserCompany = await this._dbContext.companyInfoRepository.finOneCompanyInfoByUserId(user.id); - return generateGwtToken(user, get2FaScope(user, foundUserCompany)); - } - - private async recordSignInAudit( - email: string, - userId: string | null, - status: SignInStatusEnum, - ipAddress: string, - userAgent: string, - failureReason?: string, - ): Promise { - try { - await this.signInAuditService.createSignInAuditRecord({ - email, - userId, - status, - signInMethod: SignInMethodEnum.EMAIL, - ipAddress, - userAgent, - failureReason, - }); - } catch (e) { - console.error('Failed to record sign-in audit:', e); - } - } - - private async validateRequestDomain(requestDomain: string, companyId: string): Promise { - if (!isSaaS()) { - return; - } - - const allowedDomains: Array = [`saas.rocketadmin.com`, `app.rocketadmin.com`, Constants.APP_DOMAIN_ADDRESS]; - - if (isTest()) { - allowedDomains.push(`127.0.0.1`); - if (allowedDomains.includes(requestDomain)) { - return; - } - } - - if (allowedDomains.includes(requestDomain)) { - return; - } - - if (!ValidationHelper.isValidDomain(requestDomain) && !isTest()) { - throw new BadRequestException(Messages.INVALID_REQUEST_DOMAIN_FORMAT); - } - - const companyIdByDomain: string | null = - await this.saasCompanyGatewayService.getCompanyIdByCustomDomain(requestDomain); - - if (companyIdByDomain && companyIdByDomain === companyId) { - return; - } - throw new BadRequestException(Messages.INVALID_REQUEST_DOMAIN); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly saasCompanyGatewayService: SaasCompanyGatewayService, + private readonly signInAuditService: SignInAuditService, + ) { + super(); + } + + protected async implementation(userData: UsualLoginDs): Promise { + const { request_domain, ipAddress, userAgent } = userData; + let { companyId } = userData; + const email = userData.email.toLowerCase(); + let user: UserEntity = null; + + if (companyId) { + user = await this._dbContext.userRepository.findOneUserByEmailAndCompanyId(email, companyId); + if (!user) { + await this.recordSignInAudit( + email, + null, + SignInStatusEnum.FAILED, + ipAddress, + userAgent, + Messages.USER_NOT_FOUND, + ); + throw new NotFoundException(Messages.USER_NOT_FOUND); + } + } else if (!Constants.APP_REQUEST_DOMAINS().includes(request_domain) && isSaaS()) { + const foundUserCompanyIdByDomain = + await this.saasCompanyGatewayService.getCompanyIdByCustomDomain(request_domain); + const foundUser = await this._dbContext.userRepository.findOneUserByEmailAndCompanyId( + email, + foundUserCompanyIdByDomain, + ); + if (!foundUser) { + await this.recordSignInAudit( + email, + null, + SignInStatusEnum.FAILED, + ipAddress, + userAgent, + Messages.USER_NOT_FOUND_FOR_THIS_DOMAIN, + ); + throw new BadRequestException(Messages.USER_NOT_FOUND_FOR_THIS_DOMAIN); + } + user = foundUser; + companyId = foundUser.company.id; + } else { + const foundUsers = await this._dbContext.userRepository.findAllUsersWithEmail(email); + if (foundUsers.length > 1) { + await this.recordSignInAudit( + email, + null, + SignInStatusEnum.FAILED, + ipAddress, + userAgent, + Messages.LOGIN_DENIED_SHOULD_CHOOSE_COMPANY, + ); + throw new BadRequestException(Messages.LOGIN_DENIED_SHOULD_CHOOSE_COMPANY); + } + user = foundUsers[0]; + companyId = foundUsers[0]?.company?.id; + } + + if (!user) { + await this.recordSignInAudit(email, null, SignInStatusEnum.FAILED, ipAddress, userAgent, Messages.USER_NOT_FOUND); + throw new NotFoundException(Messages.USER_NOT_FOUND); + } + if (!userData.password) { + await this.recordSignInAudit( + email, + user.id, + SignInStatusEnum.FAILED, + ipAddress, + userAgent, + Messages.PASSWORD_MISSING, + ); + throw new BadRequestException(Messages.PASSWORD_MISSING); + } + + await this.validateRequestDomain(request_domain, companyId); + + const passwordValidationResult = await Encryptor.verifyUserPassword(userData.password, user.password); + if (!passwordValidationResult) { + await this.recordSignInAudit( + email, + user.id, + SignInStatusEnum.FAILED, + ipAddress, + userAgent, + Messages.LOGIN_DENIED, + ); + throw new BadRequestException(Messages.LOGIN_DENIED); + } + if (user.isOTPEnabled) { + return generateTemporaryJwtToken(user); + } + + await this.recordSignInAudit(email, user.id, SignInStatusEnum.SUCCESS, ipAddress, userAgent); + + const foundUserCompany = await this._dbContext.companyInfoRepository.finOneCompanyInfoByUserId(user.id); + return generateGwtToken(user, get2FaScope(user, foundUserCompany)); + } + + private async recordSignInAudit( + email: string, + userId: string | null, + status: SignInStatusEnum, + ipAddress: string, + userAgent: string, + failureReason?: string, + ): Promise { + try { + await this.signInAuditService.createSignInAuditRecord({ + email, + userId, + status, + signInMethod: SignInMethodEnum.EMAIL, + ipAddress, + userAgent, + failureReason, + }); + } catch (e) { + console.error('Failed to record sign-in audit:', e); + } + } + + private async validateRequestDomain(requestDomain: string, companyId: string): Promise { + if (!isSaaS()) { + return; + } + + const allowedDomains: Array = [`saas.rocketadmin.com`, `app.rocketadmin.com`, Constants.APP_DOMAIN_ADDRESS]; + + if (isTest()) { + allowedDomains.push(`127.0.0.1`); + if (allowedDomains.includes(requestDomain)) { + return; + } + } + + if (allowedDomains.includes(requestDomain)) { + return; + } + + if (!ValidationHelper.isValidDomain(requestDomain) && !isTest()) { + throw new BadRequestException(Messages.INVALID_REQUEST_DOMAIN_FORMAT); + } + + const companyIdByDomain: string | null = + await this.saasCompanyGatewayService.getCompanyIdByCustomDomain(requestDomain); + + if (companyIdByDomain && companyIdByDomain === companyId) { + return; + } + throw new BadRequestException(Messages.INVALID_REQUEST_DOMAIN); + } } diff --git a/backend/src/entities/user/use-cases/verify-change-user-email.use.case.ts b/backend/src/entities/user/use-cases/verify-change-user-email.use.case.ts index 3ae1963c6..a70426ac0 100644 --- a/backend/src/entities/user/use-cases/verify-change-user-email.use.case.ts +++ b/backend/src/entities/user/use-cases/verify-change-user-email.use.case.ts @@ -3,11 +3,11 @@ import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { Encryptor } from '../../../helpers/encryption/encryptor.js'; import { EmailService } from '../../email/email/email.service.js'; import { ChangeUserEmailDs } from '../application/data-structures/change-user-email.ds.js'; import { OperationResultMessageDs } from '../application/data-structures/operation-result-message.ds.js'; import { IVerifyEmailChange } from './user-use-cases.interfaces.js'; -import { Encryptor } from '../../../helpers/encryption/encryptor.js'; @Injectable() export class VerifyChangeUserEmailUseCase diff --git a/backend/src/entities/user/use-cases/verify-otp-use.case.ts b/backend/src/entities/user/use-cases/verify-otp-use.case.ts index e8a7e592e..753d64457 100644 --- a/backend/src/entities/user/use-cases/verify-otp-use.case.ts +++ b/backend/src/entities/user/use-cases/verify-otp-use.case.ts @@ -1,74 +1,74 @@ -import { Injectable, Inject, HttpException, HttpStatus } from '@nestjs/common'; +import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; +import { authenticator } from 'otplib'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import { IVerifyOTP } from './user-use-cases.interfaces.js'; import { Messages } from '../../../exceptions/text/messages.js'; -import { authenticator } from 'otplib'; import { OtpValidationResultDS } from '../application/data-structures/otp-validation-result.ds.js'; import { VerifyOtpDS } from '../application/data-structures/verify-otp.ds.js'; +import { IVerifyOTP } from './user-use-cases.interfaces.js'; @Injectable() export class VerifyOtpUseCase extends AbstractUseCase implements IVerifyOTP { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: VerifyOtpDS): Promise { - const { userId, otpToken } = inputData; - const foundUser = await this._dbContext.userRepository.findOneUserById(userId); - if (!foundUser) { - throw new HttpException( - { - message: Messages.USER_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } + protected async implementation(inputData: VerifyOtpDS): Promise { + const { userId, otpToken } = inputData; + const foundUser = await this._dbContext.userRepository.findOneUserById(userId); + if (!foundUser) { + throw new HttpException( + { + message: Messages.USER_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } - if (!foundUser.isActive) { - throw new HttpException( - { - message: Messages.USER_NOT_ACTIVE, - }, - HttpStatus.BAD_REQUEST, - ); - } + if (!foundUser.isActive) { + throw new HttpException( + { + message: Messages.USER_NOT_ACTIVE, + }, + HttpStatus.BAD_REQUEST, + ); + } - const { otpSecretKey } = foundUser; - if (!otpSecretKey) { - throw new HttpException( - { - message: Messages.OTP_NOT_ENABLED, - }, - HttpStatus.BAD_REQUEST, - ); - } - try { - const isValid = authenticator.check(otpToken, otpSecretKey); - if (isValid) { - foundUser.isOTPEnabled = true; - await this._dbContext.userRepository.saveUserEntity(foundUser); - return { - validated: true, - }; - } - } catch (_error) { - throw new HttpException( - { - message: Messages.OTP_VALIDATION_FAILED, - }, - HttpStatus.BAD_REQUEST, - ); - } - throw new HttpException( - { - message: Messages.OTP_VALIDATION_FAILED, - }, - HttpStatus.INTERNAL_SERVER_ERROR, - ); - } + const { otpSecretKey } = foundUser; + if (!otpSecretKey) { + throw new HttpException( + { + message: Messages.OTP_NOT_ENABLED, + }, + HttpStatus.BAD_REQUEST, + ); + } + try { + const isValid = authenticator.check(otpToken, otpSecretKey); + if (isValid) { + foundUser.isOTPEnabled = true; + await this._dbContext.userRepository.saveUserEntity(foundUser); + return { + validated: true, + }; + } + } catch (_error) { + throw new HttpException( + { + message: Messages.OTP_VALIDATION_FAILED, + }, + HttpStatus.BAD_REQUEST, + ); + } + throw new HttpException( + { + message: Messages.OTP_VALIDATION_FAILED, + }, + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } } diff --git a/backend/src/entities/user/use-cases/verify-reset-user-password.use.case.ts b/backend/src/entities/user/use-cases/verify-reset-user-password.use.case.ts index 3b53b0ad2..4b82c8e2a 100644 --- a/backend/src/entities/user/use-cases/verify-reset-user-password.use.case.ts +++ b/backend/src/entities/user/use-cases/verify-reset-user-password.use.case.ts @@ -8,8 +8,8 @@ import { ValidationHelper } from '../../../helpers/validators/validation-helper. import { RegisteredUserDs } from '../application/data-structures/registered-user.ds.js'; import { ResetUsualUserPasswordDs } from '../application/data-structures/reset-usual-user-password.ds.js'; import { generateGwtToken } from '../utils/generate-gwt-token.js'; -import { IVerifyPasswordReset } from './user-use-cases.interfaces.js'; import { get2FaScope } from '../utils/is-jwt-scope-need.util.js'; +import { IVerifyPasswordReset } from './user-use-cases.interfaces.js'; @Injectable() export class VerifyResetUserPasswordUseCase diff --git a/backend/src/entities/user/use-cases/verify-user-email.use.case.ts b/backend/src/entities/user/use-cases/verify-user-email.use.case.ts index d347e5f5a..6bad79b19 100644 --- a/backend/src/entities/user/use-cases/verify-user-email.use.case.ts +++ b/backend/src/entities/user/use-cases/verify-user-email.use.case.ts @@ -1,11 +1,11 @@ import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { IVerifyEmail } from './user-use-cases.interfaces.js'; -import { BaseType } from '../../../common/data-injection.tokens.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; +import { BaseType } from '../../../common/data-injection.tokens.js'; import { Messages } from '../../../exceptions/text/messages.js'; -import { OperationResultMessageDs } from '../application/data-structures/operation-result-message.ds.js'; import { Encryptor } from '../../../helpers/encryption/encryptor.js'; +import { OperationResultMessageDs } from '../application/data-structures/operation-result-message.ds.js'; +import { IVerifyEmail } from './user-use-cases.interfaces.js'; @Injectable() export class VerifyUserEmailUseCase extends AbstractUseCase implements IVerifyEmail { diff --git a/backend/src/entities/user/user-email/email-change.entity.ts b/backend/src/entities/user/user-email/email-change.entity.ts index f86275c31..d976cd0d3 100644 --- a/backend/src/entities/user/user-email/email-change.entity.ts +++ b/backend/src/entities/user/user-email/email-change.entity.ts @@ -3,13 +3,17 @@ import { UserEntity } from '../user.entity.js'; @Entity('email_change') export class EmailChangeEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ default: null }) - verification_string: string; + @Column({ default: null }) + verification_string: string; - @OneToOne(() => UserEntity, (user) => user.email_change, { onDelete: 'CASCADE' }) - @JoinColumn() - user: Relation; + @OneToOne( + () => UserEntity, + (user) => user.email_change, + { onDelete: 'CASCADE' }, + ) + @JoinColumn() + user: Relation; } diff --git a/backend/src/entities/user/user-email/repository/email-change.repository.interface.ts b/backend/src/entities/user/user-email/repository/email-change.repository.interface.ts index d2605302d..0ef01ecbc 100644 --- a/backend/src/entities/user/user-email/repository/email-change.repository.interface.ts +++ b/backend/src/entities/user/user-email/repository/email-change.repository.interface.ts @@ -1,5 +1,5 @@ -import { EmailChangeEntity } from '../email-change.entity.js'; import { UserEntity } from '../../user.entity.js'; +import { EmailChangeEntity } from '../email-change.entity.js'; export interface IEmailChangeRepository { findEmailChangeWithVerificationString(verificationString: string): Promise; diff --git a/backend/src/entities/user/user-github-identifier/github-user-identifier.entity.ts b/backend/src/entities/user/user-github-identifier/github-user-identifier.entity.ts index 5ddd49e06..52a7bfaf7 100644 --- a/backend/src/entities/user/user-github-identifier/github-user-identifier.entity.ts +++ b/backend/src/entities/user/user-github-identifier/github-user-identifier.entity.ts @@ -3,16 +3,20 @@ import { UserEntity } from '../user.entity.js'; @Entity('github_user_identifier') export class GitHubUserIdentifierEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ unique: true }) - gitHubId: number; + @Column({ unique: true }) + gitHubId: number; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - createdAt: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + createdAt: Date; - @OneToOne(() => UserEntity, (user) => user.github_user_identifier, { onDelete: 'CASCADE' }) - @JoinColumn() - user: Relation; + @OneToOne( + () => UserEntity, + (user) => user.github_user_identifier, + { onDelete: 'CASCADE' }, + ) + @JoinColumn() + user: Relation; } diff --git a/backend/src/entities/user/user-github-identifier/repository/user-github-identifier-custom-repository.extension.ts b/backend/src/entities/user/user-github-identifier/repository/user-github-identifier-custom-repository.extension.ts index 9b135f674..7c076a39c 100644 --- a/backend/src/entities/user/user-github-identifier/repository/user-github-identifier-custom-repository.extension.ts +++ b/backend/src/entities/user/user-github-identifier/repository/user-github-identifier-custom-repository.extension.ts @@ -2,15 +2,15 @@ import { GitHubUserIdentifierEntity } from '../github-user-identifier.entity.js' import { IUserGitHubIdentifierRepository } from './user-github-identifier-repository.interface.js'; export const userGitHubIdentifierCustomRepositoryExtension: IUserGitHubIdentifierRepository = { - async saveGitHubIdentifierEntity( - gitHubIdentifierEntity: GitHubUserIdentifierEntity, - ): Promise { - return await this.save(gitHubIdentifierEntity); - }, + async saveGitHubIdentifierEntity( + gitHubIdentifierEntity: GitHubUserIdentifierEntity, + ): Promise { + return await this.save(gitHubIdentifierEntity); + }, - async removeGitHubIdentifierEntity( - gitHubIdentifierEntity: GitHubUserIdentifierEntity, - ): Promise { - return await this.remove(gitHubIdentifierEntity); - }, + async removeGitHubIdentifierEntity( + gitHubIdentifierEntity: GitHubUserIdentifierEntity, + ): Promise { + return await this.remove(gitHubIdentifierEntity); + }, }; diff --git a/backend/src/entities/user/user-github-identifier/repository/user-github-identifier-repository.interface.ts b/backend/src/entities/user/user-github-identifier/repository/user-github-identifier-repository.interface.ts index 76aa53834..a3e48fbd1 100644 --- a/backend/src/entities/user/user-github-identifier/repository/user-github-identifier-repository.interface.ts +++ b/backend/src/entities/user/user-github-identifier/repository/user-github-identifier-repository.interface.ts @@ -1,7 +1,7 @@ import { GitHubUserIdentifierEntity } from '../github-user-identifier.entity.js'; export interface IUserGitHubIdentifierRepository { - saveGitHubIdentifierEntity(gitHubIdentifierEntity: GitHubUserIdentifierEntity): Promise; + saveGitHubIdentifierEntity(gitHubIdentifierEntity: GitHubUserIdentifierEntity): Promise; - removeGitHubIdentifierEntity(gitHubIdentifierEntity: GitHubUserIdentifierEntity): Promise; + removeGitHubIdentifierEntity(gitHubIdentifierEntity: GitHubUserIdentifierEntity): Promise; } diff --git a/backend/src/entities/user/user-invitation/user-invitation.entity.ts b/backend/src/entities/user/user-invitation/user-invitation.entity.ts index ecdc34d46..5900308b9 100644 --- a/backend/src/entities/user/user-invitation/user-invitation.entity.ts +++ b/backend/src/entities/user/user-invitation/user-invitation.entity.ts @@ -3,19 +3,23 @@ import { UserEntity } from '../user.entity.js'; @Entity('user_invitation') export class UserInvitationEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ default: null }) - verification_string: string; + @Column({ default: null }) + verification_string: string; - @Column({ default: null }) - ownerId: string; + @Column({ default: null }) + ownerId: string; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - createdAt: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + createdAt: Date; - @OneToOne(() => UserEntity, (user) => user.user_invitation, { onDelete: 'CASCADE' }) - @JoinColumn() - user: Relation; + @OneToOne( + () => UserEntity, + (user) => user.user_invitation, + { onDelete: 'CASCADE' }, + ) + @JoinColumn() + user: Relation; } diff --git a/backend/src/entities/user/user-password/password-reset.entity.ts b/backend/src/entities/user/user-password/password-reset.entity.ts index a7dae8a8c..b6e9d6a69 100644 --- a/backend/src/entities/user/user-password/password-reset.entity.ts +++ b/backend/src/entities/user/user-password/password-reset.entity.ts @@ -3,13 +3,17 @@ import { UserEntity } from '../user.entity.js'; @Entity('password_reset') export class PasswordResetEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ default: null }) - verification_string: string; + @Column({ default: null }) + verification_string: string; - @OneToOne(() => UserEntity, (user) => user.password_reset, { onDelete: 'CASCADE' }) - @JoinColumn() - user: Relation; + @OneToOne( + () => UserEntity, + (user) => user.password_reset, + { onDelete: 'CASCADE' }, + ) + @JoinColumn() + user: Relation; } diff --git a/backend/src/entities/user/user-password/repository/password-reset-repository.interface.ts b/backend/src/entities/user/user-password/repository/password-reset-repository.interface.ts index 58913ec11..f501f090b 100644 --- a/backend/src/entities/user/user-password/repository/password-reset-repository.interface.ts +++ b/backend/src/entities/user/user-password/repository/password-reset-repository.interface.ts @@ -1,5 +1,5 @@ -import { PasswordResetEntity } from '../password-reset.entity.js'; import { UserEntity } from '../../user.entity.js'; +import { PasswordResetEntity } from '../password-reset.entity.js'; export interface IPasswordResetRepository { findPasswordResetWidthVerificationString(verificationString: string): Promise; diff --git a/backend/src/entities/user/user-session-settings/reposiotory/user-session-settings-custom-repository.extension.ts b/backend/src/entities/user/user-session-settings/reposiotory/user-session-settings-custom-repository.extension.ts index a7a6d4ad9..ed2acbfa6 100644 --- a/backend/src/entities/user/user-session-settings/reposiotory/user-session-settings-custom-repository.extension.ts +++ b/backend/src/entities/user/user-session-settings/reposiotory/user-session-settings-custom-repository.extension.ts @@ -2,26 +2,26 @@ import { UserSessionSettingsEntity } from '../user-session-settings.entity.js'; import { IUserSessionSettings } from './user-session-settings-repository.interface.js'; export const userSessionSettingsRepositoryExtension: IUserSessionSettings = { - async getUserSettingsByUserId(userId: string): Promise { - const qb = this.createQueryBuilder('user_session_settings').where('user_session_settings.userId = :userId', { - userId: userId, - }); - return await qb.getOne(); - }, + async getUserSettingsByUserId(userId: string): Promise { + const qb = this.createQueryBuilder('user_session_settings').where('user_session_settings.userId = :userId', { + userId: userId, + }); + return await qb.getOne(); + }, - async createOrUpdateUserSettings(userId: string, userSettings: string): Promise { - const qb = this.createQueryBuilder('user_session_settings').where('user_session_settings.userId = :userId', { - userId: userId, - }); - const foundUserSettings = await qb.getOne(); - if (foundUserSettings) { - foundUserSettings.userSettings = userSettings; - foundUserSettings.createdAt = new Date(); - return await this.save(foundUserSettings); - } - const newUserSettings = new UserSessionSettingsEntity(); - newUserSettings.userSettings = userSettings; - newUserSettings.userId = userId; - return await this.save(newUserSettings); - }, + async createOrUpdateUserSettings(userId: string, userSettings: string): Promise { + const qb = this.createQueryBuilder('user_session_settings').where('user_session_settings.userId = :userId', { + userId: userId, + }); + const foundUserSettings = await qb.getOne(); + if (foundUserSettings) { + foundUserSettings.userSettings = userSettings; + foundUserSettings.createdAt = new Date(); + return await this.save(foundUserSettings); + } + const newUserSettings = new UserSessionSettingsEntity(); + newUserSettings.userSettings = userSettings; + newUserSettings.userId = userId; + return await this.save(newUserSettings); + }, }; diff --git a/backend/src/entities/user/user-session-settings/reposiotory/user-session-settings-repository.interface.ts b/backend/src/entities/user/user-session-settings/reposiotory/user-session-settings-repository.interface.ts index 4de1d6d9b..24103ee9b 100644 --- a/backend/src/entities/user/user-session-settings/reposiotory/user-session-settings-repository.interface.ts +++ b/backend/src/entities/user/user-session-settings/reposiotory/user-session-settings-repository.interface.ts @@ -1,7 +1,7 @@ import { UserSessionSettingsEntity } from '../user-session-settings.entity.js'; export interface IUserSessionSettings { - getUserSettingsByUserId(userId: string): Promise; + getUserSettingsByUserId(userId: string): Promise; - createOrUpdateUserSettings(userId: string, userSettings: string): Promise; + createOrUpdateUserSettings(userId: string, userSettings: string): Promise; } diff --git a/backend/src/entities/user/user-session-settings/user-session-settings.entity.ts b/backend/src/entities/user/user-session-settings/user-session-settings.entity.ts index fdb01419a..c12426640 100644 --- a/backend/src/entities/user/user-session-settings/user-session-settings.entity.ts +++ b/backend/src/entities/user/user-session-settings/user-session-settings.entity.ts @@ -1,16 +1,16 @@ -import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'; +import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm'; @Entity('user_session_settings') export class UserSessionSettingsEntity { - @PrimaryGeneratedColumn('uuid') - id: string; + @PrimaryGeneratedColumn('uuid') + id: string; - @Column({ nullable: false, unique: true, type: 'uuid' }) - userId: string; + @Column({ nullable: false, unique: true, type: 'uuid' }) + userId: string; - @Column({ default: null, type: 'json' }) - userSettings: string; + @Column({ default: null, type: 'json' }) + userSettings: string; - @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) - createdAt: Date; + @Column({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' }) + createdAt: Date; } diff --git a/backend/src/entities/user/user.controller.ts b/backend/src/entities/user/user.controller.ts index 16bf7ccbd..2d8cb700d 100644 --- a/backend/src/entities/user/user.controller.ts +++ b/backend/src/entities/user/user.controller.ts @@ -14,15 +14,20 @@ import { Res, UseInterceptors, } from '@nestjs/common'; -import { Response, Request } from 'express'; +import { ApiBearerAuth, ApiBody, ApiOperation, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger'; +import { Throttle } from '@nestjs/throttler'; +import { Request, Response } from 'express'; import isEmail from 'validator/lib/isEmail.js'; import { UseCaseType } from '../../common/data-injection.tokens.js'; import { BodyEmail, GCLlId, UserId, VerificationString } from '../../decorators/index.js'; +import { Timeout } from '../../decorators/timeout.decorator.js'; import { InTransactionEnum } from '../../enums/index.js'; import { Messages } from '../../exceptions/text/messages.js'; -import { slackPostMessage } from '../../helpers/index.js'; +import { isTest } from '../../helpers/app/is-test.js'; import { Constants } from '../../helpers/constants/constants.js'; +import { slackPostMessage } from '../../helpers/index.js'; import { SentryInterceptor } from '../../interceptors/index.js'; +import { SuccessResponse } from '../../microservices/saas-microservice/data-structures/common-responce.ds.js'; import { ChangeUserEmailDs } from './application/data-structures/change-user-email.ds.js'; import { ChangeUserNameDS } from './application/data-structures/change-user-name.ds.js'; import { @@ -30,11 +35,21 @@ import { ChangeUsualUserPasswordDto, } from './application/data-structures/change-usual-user-password.ds.js'; import { FindUserDs } from './application/data-structures/find-user.ds.js'; -import { FoundUserDto } from './dto/found-user.dto.js'; import { OperationResultMessageDs } from './application/data-structures/operation-result-message.ds.js'; +import { OtpSecretDS } from './application/data-structures/otp-secret.ds.js'; +import { OtpDisablingResultDS, OtpValidationResultDS } from './application/data-structures/otp-validation-result.ds.js'; import { RegisteredUserDs } from './application/data-structures/registered-user.ds.js'; import { ResetUsualUserPasswordDs } from './application/data-structures/reset-usual-user-password.ds.js'; import { UsualLoginDs } from './application/data-structures/usual-login.ds.js'; +import { DeleteUserAccountDTO } from './dto/delete-user-account-request.dto.js'; +import { EmailDto } from './dto/email.dto.js'; +import { FoundUserDto } from './dto/found-user.dto.js'; +import { LoginUserDto } from './dto/login-user.dto.js'; +import { OtpTokenDto } from './dto/otp-token.dto.js'; +import { PasswordDto } from './dto/password.dto.js'; +import { RequestRestUserPasswordDto } from './dto/request-rest-user-password.dto.js'; +import { UserNameDto } from './dto/user-name.dto.js'; +import { UserSettingsDataRequestDto } from './dto/user-settings-data-request.dto.js'; import { IChangeUserName, IDeleteUserAccount, @@ -57,22 +72,7 @@ import { IVerifyPasswordReset, } from './use-cases/user-use-cases.interfaces.js'; import { ITokenExp, TokenExpDs } from './utils/generate-gwt-token.js'; -import { OtpSecretDS } from './application/data-structures/otp-secret.ds.js'; -import { OtpDisablingResultDS, OtpValidationResultDS } from './application/data-structures/otp-validation-result.ds.js'; import { getCookieDomainOptions } from './utils/get-cookie-domain-options.js'; -import { ApiBearerAuth, ApiBody, ApiOperation, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger'; -import { PasswordDto } from './dto/password.dto.js'; -import { EmailDto } from './dto/email.dto.js'; -import { DeleteUserAccountDTO } from './dto/delete-user-account-request.dto.js'; -import { LoginUserDto } from './dto/login-user.dto.js'; -import { UserNameDto } from './dto/user-name.dto.js'; -import { OtpTokenDto } from './dto/otp-token.dto.js'; -import { UserSettingsDataRequestDto } from './dto/user-settings-data-request.dto.js'; -import { RequestRestUserPasswordDto } from './dto/request-rest-user-password.dto.js'; -import { SuccessResponse } from '../../microservices/saas-microservice/data-structures/common-responce.ds.js'; -import { Timeout } from '../../decorators/timeout.decorator.js'; -import { Throttle } from '@nestjs/throttler'; -import { isTest } from '../../helpers/app/is-test.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/user/user.entity.ts b/backend/src/entities/user/user.entity.ts index ccc15bb07..5f8095090 100644 --- a/backend/src/entities/user/user.entity.ts +++ b/backend/src/entities/user/user.entity.ts @@ -1,35 +1,35 @@ -import { ConnectionEntity } from '../connection/connection.entity.js'; import { - Entity, + AfterLoad, + BeforeInsert, + BeforeUpdate, Column, + Entity, JoinTable, ManyToMany, + ManyToOne, OneToMany, OneToOne, PrimaryGeneratedColumn, - BeforeInsert, Relation, - BeforeUpdate, - AfterLoad, - ManyToOne, } from 'typeorm'; -import { GroupEntity } from '../group/group.entity.js'; -import { UserActionEntity } from '../user-actions/user-action.entity.js'; import { Encryptor } from '../../helpers/encryption/encryptor.js'; -import { EmailVerificationEntity } from '../email/email-verification.entity.js'; -import { PasswordResetEntity } from './user-password/password-reset.entity.js'; -import { EmailChangeEntity } from './user-email/email-change.entity.js'; -import { UserInvitationEntity } from './user-invitation/user-invitation.entity.js'; -import { GitHubUserIdentifierEntity } from './user-github-identifier/github-user-identifier.entity.js'; -import { CompanyInfoEntity } from '../company-info/company-info.entity.js'; -import { UserRoleEnum } from './enums/user-role.enum.js'; -import { ExternalRegistrationProviderEnum } from './enums/external-registration-provider.enum.js'; -import { UserApiKeyEntity } from '../api-key/api-key.entity.js'; +import { UserAiChatEntity } from '../ai/ai-conversation-history/user-ai-chat/user-ai-chat.entity.js'; import { AiResponsesToUserEntity } from '../ai/ai-data-entities/ai-reponses-to-user/ai-responses-to-user.entity.js'; -import { SignInAuditEntity } from '../user-sign-in-audit/sign-in-audit.entity.js'; +import { UserApiKeyEntity } from '../api-key/api-key.entity.js'; +import { CompanyInfoEntity } from '../company-info/company-info.entity.js'; +import { ConnectionEntity } from '../connection/connection.entity.js'; +import { EmailVerificationEntity } from '../email/email-verification.entity.js'; +import { GroupEntity } from '../group/group.entity.js'; import { SecretAccessLogEntity } from '../secret-access-log/secret-access-log.entity.js'; import { PersonalTableSettingsEntity } from '../table-settings/personal-table-settings/personal-table-settings.entity.js'; -import { UserAiChatEntity } from '../ai/ai-conversation-history/user-ai-chat/user-ai-chat.entity.js'; +import { UserActionEntity } from '../user-actions/user-action.entity.js'; +import { SignInAuditEntity } from '../user-sign-in-audit/sign-in-audit.entity.js'; +import { ExternalRegistrationProviderEnum } from './enums/external-registration-provider.enum.js'; +import { UserRoleEnum } from './enums/user-role.enum.js'; +import { EmailChangeEntity } from './user-email/email-change.entity.js'; +import { GitHubUserIdentifierEntity } from './user-github-identifier/github-user-identifier.entity.js'; +import { UserInvitationEntity } from './user-invitation/user-invitation.entity.js'; +import { PasswordResetEntity } from './user-password/password-reset.entity.js'; @Entity('user') export class UserEntity { diff --git a/backend/src/entities/user/user.interface.ts b/backend/src/entities/user/user.interface.ts index 628397b6b..f30f1a877 100644 --- a/backend/src/entities/user/user.interface.ts +++ b/backend/src/entities/user/user.interface.ts @@ -1,11 +1,11 @@ import { SubscriptionLevelEnum } from '../../enums/index.js'; export interface IUserInfo { - id: string; - isActive: boolean; - email: string; - createdAt: Date; - portal_link?: string; - subscriptionLevel: SubscriptionLevelEnum; - name: string; + id: string; + isActive: boolean; + email: string; + createdAt: Date; + portal_link?: string; + subscriptionLevel: SubscriptionLevelEnum; + name: string; } diff --git a/backend/src/entities/user/user.module.ts b/backend/src/entities/user/user.module.ts index ba76c5d24..6961ffd70 100644 --- a/backend/src/entities/user/user.module.ts +++ b/backend/src/entities/user/user.module.ts @@ -1,176 +1,176 @@ import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { AuthMiddleware } from '../../authorization/index.js'; +import { NonScopedAuthMiddleware } from '../../authorization/non-scoped-auth.middleware.js'; +import { TemporaryAuthMiddleware } from '../../authorization/temporary-auth.middleware.js'; import { GlobalDatabaseContext } from '../../common/application/global-database-context.js'; import { BaseType, UseCaseType } from '../../common/data-injection.tokens.js'; import { AgentModule } from '../agent/agent.module.js'; -import { ConnectionPropertiesEntity } from '../connection-properties/connection-properties.entity.js'; +import { CompanyInfoEntity } from '../company-info/company-info.entity.js'; import { ConnectionEntity } from '../connection/connection.entity.js'; +import { ConnectionPropertiesEntity } from '../connection-properties/connection-properties.entity.js'; import { CustomFieldsEntity } from '../custom-field/custom-fields.entity.js'; import { GroupEntity } from '../group/group.entity.js'; import { LogOutEntity } from '../log-out/log-out.entity.js'; import { PermissionEntity } from '../permission/permission.entity.js'; import { TableLogsEntity } from '../table-logs/table-logs.entity.js'; import { TableSettingsEntity } from '../table-settings/common-table-settings/table-settings.entity.js'; +import { SignInAuditEntity } from '../user-sign-in-audit/sign-in-audit.entity.js'; +import { SignInAuditService } from '../user-sign-in-audit/sign-in-audit.service.js'; import { TableWidgetEntity } from '../widget/table-widget.entity.js'; import { ChangeUserNameUseCase } from './use-cases/change-user-name-use.case.js'; import { ChangeUsualPasswordUseCase } from './use-cases/change-usual-password-use.case.js'; import { DeleteUserAccountUseCase } from './use-cases/delete-user-account-use-case.js'; +import { DisableOtpUseCase } from './use-cases/disable-otp.use.case.js'; import { FindUserUseCase } from './use-cases/find-user-use.case.js'; +import { GenerateOtpUseCase } from './use-cases/generate-otp-use.case.js'; +import { GetUserSessionSettingsUseCase } from './use-cases/get-user-session-settings.use.case.js'; import { LogOutUseCase } from './use-cases/log-out.use.case.js'; +import { OtpLoginUseCase } from './use-cases/otp-login-use.case.js'; import { RequestChangeUserEmailUseCase } from './use-cases/request-change-user-email.use.case.js'; import { RequestEmailVerificationUseCase } from './use-cases/request-email-verification.use.case.js'; import { RequestResetUserPasswordUseCase } from './use-cases/request-reset-user-password.use.case.js'; +import { SaveUserSettingsUseCase } from './use-cases/save-user-session-settings.use.case.js'; +import { ToggleTestConnectionsDisplayModeUseCase } from './use-cases/toggle-test-connections-display-mode.use.case.js'; import { UsualLoginUseCase } from './use-cases/usual-login-use.case.js'; import { VerifyChangeUserEmailUseCase } from './use-cases/verify-change-user-email.use.case.js'; +import { VerifyOtpUseCase } from './use-cases/verify-otp-use.case.js'; import { VerifyResetUserPasswordUseCase } from './use-cases/verify-reset-user-password.use.case.js'; import { VerifyUserEmailUseCase } from './use-cases/verify-user-email.use.case.js'; -import { UserHelperService } from './user-helper.service.js'; import { UserController } from './user.controller.js'; import { UserEntity } from './user.entity.js'; -import { GenerateOtpUseCase } from './use-cases/generate-otp-use.case.js'; -import { VerifyOtpUseCase } from './use-cases/verify-otp-use.case.js'; -import { OtpLoginUseCase } from './use-cases/otp-login-use.case.js'; -import { TemporaryAuthMiddleware } from '../../authorization/temporary-auth.middleware.js'; -import { DisableOtpUseCase } from './use-cases/disable-otp.use.case.js'; -import { GetUserSessionSettingsUseCase } from './use-cases/get-user-session-settings.use.case.js'; -import { SaveUserSettingsUseCase } from './use-cases/save-user-session-settings.use.case.js'; -import { CompanyInfoEntity } from '../company-info/company-info.entity.js'; -import { NonScopedAuthMiddleware } from '../../authorization/non-scoped-auth.middleware.js'; -import { ToggleTestConnectionsDisplayModeUseCase } from './use-cases/toggle-test-connections-display-mode.use.case.js'; -import { SignInAuditEntity } from '../user-sign-in-audit/sign-in-audit.entity.js'; -import { SignInAuditService } from '../user-sign-in-audit/sign-in-audit.service.js'; +import { UserHelperService } from './user-helper.service.js'; @Module({ - imports: [ - TypeOrmModule.forFeature([ - ConnectionEntity, - CustomFieldsEntity, - GroupEntity, - PermissionEntity, - TableLogsEntity, - TableSettingsEntity, - TableWidgetEntity, - UserEntity, - ConnectionPropertiesEntity, - LogOutEntity, - CompanyInfoEntity, - SignInAuditEntity, - ]), - AgentModule, - ], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.FIND_USER, - useClass: FindUserUseCase, - }, - { - provide: UseCaseType.USUAL_LOGIN, - useClass: UsualLoginUseCase, - }, - { - provide: UseCaseType.LOG_OUT, - useClass: LogOutUseCase, - }, - { - provide: UseCaseType.CHANGE_USUAL_PASSWORD, - useClass: ChangeUsualPasswordUseCase, - }, - { - provide: UseCaseType.VERIFY_EMAIL, - useClass: VerifyUserEmailUseCase, - }, - { - provide: UseCaseType.VERIFY_RESET_USER_PASSWORD, - useClass: VerifyResetUserPasswordUseCase, - }, - { - provide: UseCaseType.REQUEST_RESET_USER_PASSWORD, - useClass: RequestResetUserPasswordUseCase, - }, - { - provide: UseCaseType.REQUEST_CHANGE_USER_EMAIL, - useClass: RequestChangeUserEmailUseCase, - }, - { - provide: UseCaseType.VERIFY_EMAIL_CHANGE, - useClass: VerifyChangeUserEmailUseCase, - }, - { - provide: UseCaseType.VERIFY_EMAIL_REQUEST, - useClass: RequestEmailVerificationUseCase, - }, - { - provide: UseCaseType.DELETE_USER_ACCOUNT, - useClass: DeleteUserAccountUseCase, - }, - { - provide: UseCaseType.CHANGE_USER_NAME, - useClass: ChangeUserNameUseCase, - }, - { - provide: UseCaseType.GENERATE_OTP, - useClass: GenerateOtpUseCase, - }, - { - provide: UseCaseType.VERIFY_OTP, - useClass: VerifyOtpUseCase, - }, - { - provide: UseCaseType.OTP_LOGIN, - useClass: OtpLoginUseCase, - }, - { - provide: UseCaseType.DISABLE_OTP, - useClass: DisableOtpUseCase, - }, - { - provide: UseCaseType.SAVE_USER_SESSION_SETTINGS, - useClass: SaveUserSettingsUseCase, - }, - { - provide: UseCaseType.GET_USER_SESSION_SETTINGS, - useClass: GetUserSessionSettingsUseCase, - }, - { - provide: UseCaseType.TOGGLE_TEST_CONNECTIONS_DISPLAY_MODE, - useClass: ToggleTestConnectionsDisplayModeUseCase, - }, - UserHelperService, - SignInAuditService, - ], - controllers: [UserController], - exports: [UserHelperService], + imports: [ + TypeOrmModule.forFeature([ + ConnectionEntity, + CustomFieldsEntity, + GroupEntity, + PermissionEntity, + TableLogsEntity, + TableSettingsEntity, + TableWidgetEntity, + UserEntity, + ConnectionPropertiesEntity, + LogOutEntity, + CompanyInfoEntity, + SignInAuditEntity, + ]), + AgentModule, + ], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.FIND_USER, + useClass: FindUserUseCase, + }, + { + provide: UseCaseType.USUAL_LOGIN, + useClass: UsualLoginUseCase, + }, + { + provide: UseCaseType.LOG_OUT, + useClass: LogOutUseCase, + }, + { + provide: UseCaseType.CHANGE_USUAL_PASSWORD, + useClass: ChangeUsualPasswordUseCase, + }, + { + provide: UseCaseType.VERIFY_EMAIL, + useClass: VerifyUserEmailUseCase, + }, + { + provide: UseCaseType.VERIFY_RESET_USER_PASSWORD, + useClass: VerifyResetUserPasswordUseCase, + }, + { + provide: UseCaseType.REQUEST_RESET_USER_PASSWORD, + useClass: RequestResetUserPasswordUseCase, + }, + { + provide: UseCaseType.REQUEST_CHANGE_USER_EMAIL, + useClass: RequestChangeUserEmailUseCase, + }, + { + provide: UseCaseType.VERIFY_EMAIL_CHANGE, + useClass: VerifyChangeUserEmailUseCase, + }, + { + provide: UseCaseType.VERIFY_EMAIL_REQUEST, + useClass: RequestEmailVerificationUseCase, + }, + { + provide: UseCaseType.DELETE_USER_ACCOUNT, + useClass: DeleteUserAccountUseCase, + }, + { + provide: UseCaseType.CHANGE_USER_NAME, + useClass: ChangeUserNameUseCase, + }, + { + provide: UseCaseType.GENERATE_OTP, + useClass: GenerateOtpUseCase, + }, + { + provide: UseCaseType.VERIFY_OTP, + useClass: VerifyOtpUseCase, + }, + { + provide: UseCaseType.OTP_LOGIN, + useClass: OtpLoginUseCase, + }, + { + provide: UseCaseType.DISABLE_OTP, + useClass: DisableOtpUseCase, + }, + { + provide: UseCaseType.SAVE_USER_SESSION_SETTINGS, + useClass: SaveUserSettingsUseCase, + }, + { + provide: UseCaseType.GET_USER_SESSION_SETTINGS, + useClass: GetUserSessionSettingsUseCase, + }, + { + provide: UseCaseType.TOGGLE_TEST_CONNECTIONS_DISPLAY_MODE, + useClass: ToggleTestConnectionsDisplayModeUseCase, + }, + UserHelperService, + SignInAuditService, + ], + controllers: [UserController], + exports: [UserHelperService], }) export class UserModule implements NestModule { - public configure(consumer: MiddlewareConsumer): void { - consumer - .apply(AuthMiddleware) - .forRoutes( - { path: 'user', method: RequestMethod.GET }, - { path: 'user', method: RequestMethod.PUT }, - { path: 'user/name/', method: RequestMethod.PUT }, - { path: 'user/permissions/:slug', method: RequestMethod.GET }, - { path: 'user/logout/', method: RequestMethod.POST }, - { path: 'user/email/verify/request', method: RequestMethod.GET }, - { path: 'user/delete/', method: RequestMethod.PUT }, - { path: 'user/email/change/request', method: RequestMethod.GET }, - { path: 'user/settings', method: RequestMethod.POST }, - { path: 'user/settings', method: RequestMethod.GET }, - { path: 'user/test/connections/display/', method: RequestMethod.PUT }, - { path: 'user/password/change', method: RequestMethod.POST }, - ) - .apply(TemporaryAuthMiddleware) - .forRoutes({ path: 'user/otp/login', method: RequestMethod.POST }) - .apply(NonScopedAuthMiddleware) - .forRoutes( - { path: 'user/otp/generate', method: RequestMethod.POST }, - { path: 'user/otp/verify', method: RequestMethod.POST }, - { path: 'user/otp/disable', method: RequestMethod.POST }, - ); - } + public configure(consumer: MiddlewareConsumer): void { + consumer + .apply(AuthMiddleware) + .forRoutes( + { path: 'user', method: RequestMethod.GET }, + { path: 'user', method: RequestMethod.PUT }, + { path: 'user/name/', method: RequestMethod.PUT }, + { path: 'user/permissions/:slug', method: RequestMethod.GET }, + { path: 'user/logout/', method: RequestMethod.POST }, + { path: 'user/email/verify/request', method: RequestMethod.GET }, + { path: 'user/delete/', method: RequestMethod.PUT }, + { path: 'user/email/change/request', method: RequestMethod.GET }, + { path: 'user/settings', method: RequestMethod.POST }, + { path: 'user/settings', method: RequestMethod.GET }, + { path: 'user/test/connections/display/', method: RequestMethod.PUT }, + { path: 'user/password/change', method: RequestMethod.POST }, + ) + .apply(TemporaryAuthMiddleware) + .forRoutes({ path: 'user/otp/login', method: RequestMethod.POST }) + .apply(NonScopedAuthMiddleware) + .forRoutes( + { path: 'user/otp/generate', method: RequestMethod.POST }, + { path: 'user/otp/verify', method: RequestMethod.POST }, + { path: 'user/otp/disable', method: RequestMethod.POST }, + ); + } } diff --git a/backend/src/entities/user/utils/build-connection-entities-from-test-dtos.ts b/backend/src/entities/user/utils/build-connection-entities-from-test-dtos.ts index a7b4ddb52..7fea598c9 100644 --- a/backend/src/entities/user/utils/build-connection-entities-from-test-dtos.ts +++ b/backend/src/entities/user/utils/build-connection-entities-from-test-dtos.ts @@ -2,30 +2,30 @@ import { CreateConnectionDto } from '../../connection/application/dto/create-con import { ConnectionEntity } from '../../connection/connection.entity.js'; export function buildConnectionEntitiesFromTestDtos(dtos: Array): Array { - const entities: Array = []; - for (const dto of dtos) { - const connection = new ConnectionEntity(); - connection.title = dto.title; - connection.masterEncryption = dto.masterEncryption || false; - connection.type = dto.type; - connection.host = dto.host; - connection.port = dto.port; - connection.username = dto.username; - connection.password = dto.password; - connection.database = dto.database; - connection.schema = dto.schema; - connection.sid = dto.sid; - connection.ssh = dto.ssh || false; - connection.privateSSHKey = dto.privateSSHKey; - connection.sshHost = dto.sshHost; - connection.sshPort = dto.sshPort; - connection.sshUsername = dto.sshUsername; - connection.ssl = dto.ssl || false; - connection.cert = dto.cert; - connection.azure_encryption = dto.azure_encryption || false; - connection.isTestConnection = dto.isTestConnection; - connection.authSource = dto.authSource; - entities.push(connection); - } - return entities; + const entities: Array = []; + for (const dto of dtos) { + const connection = new ConnectionEntity(); + connection.title = dto.title; + connection.masterEncryption = dto.masterEncryption || false; + connection.type = dto.type; + connection.host = dto.host; + connection.port = dto.port; + connection.username = dto.username; + connection.password = dto.password; + connection.database = dto.database; + connection.schema = dto.schema; + connection.sid = dto.sid; + connection.ssh = dto.ssh || false; + connection.privateSSHKey = dto.privateSSHKey; + connection.sshHost = dto.sshHost; + connection.sshPort = dto.sshPort; + connection.sshUsername = dto.sshUsername; + connection.ssl = dto.ssl || false; + connection.cert = dto.cert; + connection.azure_encryption = dto.azure_encryption || false; + connection.isTestConnection = dto.isTestConnection; + connection.authSource = dto.authSource; + entities.push(connection); + } + return entities; } diff --git a/backend/src/entities/user/utils/build-created-user.ds.ts b/backend/src/entities/user/utils/build-created-user.ds.ts index d4aa56c56..01a0edac3 100644 --- a/backend/src/entities/user/utils/build-created-user.ds.ts +++ b/backend/src/entities/user/utils/build-created-user.ds.ts @@ -2,18 +2,18 @@ import { SimpleFoundUserInfoDs } from '../dto/found-user.dto.js'; import { UserEntity } from '../user.entity.js'; export function buildSimpleUserInfoDs(user: UserEntity): SimpleFoundUserInfoDs { - if (!user) { - return null; - } - return { - id: user.id, - isActive: user.isActive, - email: user.email, - createdAt: user.createdAt, - suspended: user.suspended, - name: user.name, - is_2fa_enabled: user.isOTPEnabled, - role: user.role, - externalRegistrationProvider: user.externalRegistrationProvider, - }; + if (!user) { + return null; + } + return { + id: user.id, + isActive: user.isActive, + email: user.email, + createdAt: user.createdAt, + suspended: user.suspended, + name: user.name, + is_2fa_enabled: user.isOTPEnabled, + role: user.role, + externalRegistrationProvider: user.externalRegistrationProvider, + }; } diff --git a/backend/src/entities/user/utils/build-default-admin-groups.ts b/backend/src/entities/user/utils/build-default-admin-groups.ts index 8dee1724f..e4844273c 100644 --- a/backend/src/entities/user/utils/build-default-admin-groups.ts +++ b/backend/src/entities/user/utils/build-default-admin-groups.ts @@ -1,17 +1,17 @@ -import { UserEntity } from '../user.entity.js'; -import { GroupEntity } from '../../group/group.entity.js'; import { ConnectionEntity } from '../../connection/connection.entity.js'; +import { GroupEntity } from '../../group/group.entity.js'; +import { UserEntity } from '../user.entity.js'; export function buildDefaultAdminGroups(user: UserEntity, connections: Array): Array { - const createdGroups: Array = []; - for (const connection of connections) { - const group = new GroupEntity(); - group.title = 'Admin'; - group.isMain = true; - group.users = [user]; - group.connection = connection; - group.permissions = []; - createdGroups.push(group); - } - return createdGroups; + const createdGroups: Array = []; + for (const connection of connections) { + const group = new GroupEntity(); + group.title = 'Admin'; + group.isMain = true; + group.users = [user]; + group.connection = connection; + group.permissions = []; + createdGroups.push(group); + } + return createdGroups; } diff --git a/backend/src/entities/user/utils/build-default-admin-permissions.ts b/backend/src/entities/user/utils/build-default-admin-permissions.ts index 5e7fe2b34..3c16fac93 100644 --- a/backend/src/entities/user/utils/build-default-admin-permissions.ts +++ b/backend/src/entities/user/utils/build-default-admin-permissions.ts @@ -1,25 +1,25 @@ -import { PermissionEntity } from '../../permission/permission.entity.js'; -import { GroupEntity } from '../../group/group.entity.js'; import { AccessLevelEnum, PermissionTypeEnum } from '../../../enums/index.js'; +import { GroupEntity } from '../../group/group.entity.js'; +import { PermissionEntity } from '../../permission/permission.entity.js'; export function buildDefaultAdminPermissions(groups: Array): Array { - const permissions: Array = []; - for (const group of groups) { - const connectionAdminPermission = new PermissionEntity(); - connectionAdminPermission.type = PermissionTypeEnum.Connection; - connectionAdminPermission.accessLevel = AccessLevelEnum.edit; - connectionAdminPermission.groups = []; - connectionAdminPermission.groups.push(group); + const permissions: Array = []; + for (const group of groups) { + const connectionAdminPermission = new PermissionEntity(); + connectionAdminPermission.type = PermissionTypeEnum.Connection; + connectionAdminPermission.accessLevel = AccessLevelEnum.edit; + connectionAdminPermission.groups = []; + connectionAdminPermission.groups.push(group); - permissions.push(connectionAdminPermission); + permissions.push(connectionAdminPermission); - const groupAdminPermission = new PermissionEntity(); - groupAdminPermission.type = PermissionTypeEnum.Group; - groupAdminPermission.accessLevel = AccessLevelEnum.edit; - groupAdminPermission.groups = []; - groupAdminPermission.groups.push(group); + const groupAdminPermission = new PermissionEntity(); + groupAdminPermission.type = PermissionTypeEnum.Group; + groupAdminPermission.accessLevel = AccessLevelEnum.edit; + groupAdminPermission.groups = []; + groupAdminPermission.groups.push(group); - permissions.push(groupAdminPermission); - } - return permissions; + permissions.push(groupAdminPermission); + } + return permissions; } diff --git a/backend/src/entities/user/utils/build-found-user.dto.ts b/backend/src/entities/user/utils/build-found-user.dto.ts index 5d37c5db5..e30e0ec89 100644 --- a/backend/src/entities/user/utils/build-found-user.dto.ts +++ b/backend/src/entities/user/utils/build-found-user.dto.ts @@ -2,16 +2,16 @@ import { FoundUserDto } from '../dto/found-user.dto.js'; import { UserEntity } from '../user.entity.js'; export function buildFoundUserDto(user: UserEntity): FoundUserDto { - return { - id: user.id, - isActive: user.isActive, - email: user.email, - createdAt: user.createdAt, - name: user.name, - suspended: user.suspended, - role: user.role, - is_2fa_enabled: user.otpSecretKey !== null && user.isOTPEnabled, - externalRegistrationProvider: user.externalRegistrationProvider, - show_test_connections: user.showTestConnections, - }; + return { + id: user.id, + isActive: user.isActive, + email: user.email, + createdAt: user.createdAt, + name: user.name, + suspended: user.suspended, + role: user.role, + is_2fa_enabled: user.otpSecretKey !== null && user.isOTPEnabled, + externalRegistrationProvider: user.externalRegistrationProvider, + show_test_connections: user.showTestConnections, + }; } diff --git a/backend/src/entities/user/utils/build-github-identifier-entity.ts b/backend/src/entities/user/utils/build-github-identifier-entity.ts index e7ebc0cb2..410520fc0 100644 --- a/backend/src/entities/user/utils/build-github-identifier-entity.ts +++ b/backend/src/entities/user/utils/build-github-identifier-entity.ts @@ -1,9 +1,9 @@ -import { GitHubUserIdentifierEntity } from '../user-github-identifier/github-user-identifier.entity.js'; import { UserEntity } from '../user.entity.js'; +import { GitHubUserIdentifierEntity } from '../user-github-identifier/github-user-identifier.entity.js'; export function buildUserGitHubIdentifierEntity(user: UserEntity, gitHubId: number): GitHubUserIdentifierEntity { - const gitHubIdentifierEntity = new GitHubUserIdentifierEntity(); - gitHubIdentifierEntity.user = user; - gitHubIdentifierEntity.gitHubId = gitHubId; - return gitHubIdentifierEntity; + const gitHubIdentifierEntity = new GitHubUserIdentifierEntity(); + gitHubIdentifierEntity.user = user; + gitHubIdentifierEntity.gitHubId = gitHubId; + return gitHubIdentifierEntity; } diff --git a/backend/src/entities/user/utils/build-registering-user.util.ts b/backend/src/entities/user/utils/build-registering-user.util.ts index a1538e293..7d7a03522 100644 --- a/backend/src/entities/user/utils/build-registering-user.util.ts +++ b/backend/src/entities/user/utils/build-registering-user.util.ts @@ -3,12 +3,12 @@ import { UserRoleEnum } from '../enums/user-role.enum.js'; import { UserEntity } from '../user.entity.js'; export function buildRegisteringUser(userData: RegisterUserDs): UserEntity { - const newUser: UserEntity = new UserEntity(); - newUser.gclid = userData.gclidValue; - newUser.email = userData.email?.toLowerCase(); - newUser.password = userData.password; - newUser.isActive = userData.isActive; - newUser.name = userData.name; - newUser.role = userData.role ? userData.role : UserRoleEnum.USER; - return newUser; + const newUser: UserEntity = new UserEntity(); + newUser.gclid = userData.gclidValue; + newUser.email = userData.email?.toLowerCase(); + newUser.password = userData.password; + newUser.isActive = userData.isActive; + newUser.name = userData.name; + newUser.role = userData.role ? userData.role : UserRoleEnum.USER; + return newUser; } diff --git a/backend/src/entities/user/utils/generate-gwt-token.ts b/backend/src/entities/user/utils/generate-gwt-token.ts index 364c02776..c34ccca6c 100644 --- a/backend/src/entities/user/utils/generate-gwt-token.ts +++ b/backend/src/entities/user/utils/generate-gwt-token.ts @@ -1,64 +1,64 @@ -import jwt from 'jsonwebtoken'; -import { UserEntity } from '../user.entity.js'; import { ApiProperty } from '@nestjs/swagger'; +import jwt from 'jsonwebtoken'; import { JwtScopesEnum } from '../enums/jwt-scopes.enum.js'; +import { UserEntity } from '../user.entity.js'; export function generateGwtToken(user: UserEntity, scope: Array): IToken { - const today = new Date(); - const exp = new Date(today); - exp.setTime(today.getTime() + 60 * 60 * 1000 * 24 * 7); - const jwtSecret = process.env.JWT_SECRET; - const token = jwt.sign( - { - id: user.id, - email: user.email, - exp: Math.floor(exp.getTime() / 1000), - scope: scope ? scope : undefined, - }, - jwtSecret, - ); - return { - exp: exp, - token: token, - isTemporary: false, - }; + const today = new Date(); + const exp = new Date(today); + exp.setTime(today.getTime() + 60 * 60 * 1000 * 24 * 7); + const jwtSecret = process.env.JWT_SECRET; + const token = jwt.sign( + { + id: user.id, + email: user.email, + exp: Math.floor(exp.getTime() / 1000), + scope: scope ? scope : undefined, + }, + jwtSecret, + ); + return { + exp: exp, + token: token, + isTemporary: false, + }; } export function generateTemporaryJwtToken(user: UserEntity): IToken { - const today = new Date(); - const exp = new Date(today); - exp.setTime(today.getTime() + 1000 * 60 * 4); - const jwtSecret = process.env.TEMPORARY_JWT_SECRET; - const token = jwt.sign( - { - id: user.id, - email: user.email, - exp: Math.floor(exp.getTime() / 1000), - }, - jwtSecret, - ); - return { - exp: exp, - token: token, - isTemporary: true, - }; + const today = new Date(); + const exp = new Date(today); + exp.setTime(today.getTime() + 1000 * 60 * 4); + const jwtSecret = process.env.TEMPORARY_JWT_SECRET; + const token = jwt.sign( + { + id: user.id, + email: user.email, + exp: Math.floor(exp.getTime() / 1000), + }, + jwtSecret, + ); + return { + exp: exp, + token: token, + isTemporary: true, + }; } export interface IToken { - exp: Date; - token: string; - isTemporary: boolean; + exp: Date; + token: string; + isTemporary: boolean; } export interface ITokenExp { - expires: Date; - isTemporary: boolean; + expires: Date; + isTemporary: boolean; } export class TokenExpDs { - @ApiProperty({ type: Date }) - expires: Date; + @ApiProperty({ type: Date }) + expires: Date; - @ApiProperty() - isTemporary: boolean; + @ApiProperty() + isTemporary: boolean; } diff --git a/backend/src/entities/user/utils/generate-qr-code.ts b/backend/src/entities/user/utils/generate-qr-code.ts index fe92234d7..8f0023364 100644 --- a/backend/src/entities/user/utils/generate-qr-code.ts +++ b/backend/src/entities/user/utils/generate-qr-code.ts @@ -1,9 +1,9 @@ -import QRCode from 'qrcode'; import { authenticator } from 'otplib'; +import QRCode from 'qrcode'; export async function generateQRCode(userEmail: string, secretKey: string) { - const service = 'Rocketadmin'; - const otpauth = authenticator.keyuri(userEmail, service, secretKey); - const qrCode = await QRCode.toDataURL(otpauth); - return { qrCode, otpauth }; + const service = 'Rocketadmin'; + const otpauth = authenticator.keyuri(userEmail, service, secretKey); + const qrCode = await QRCode.toDataURL(otpauth); + return { qrCode, otpauth }; } diff --git a/backend/src/entities/user/utils/get-cookie-domain-options.ts b/backend/src/entities/user/utils/get-cookie-domain-options.ts index 5902a4b05..05bb61876 100644 --- a/backend/src/entities/user/utils/get-cookie-domain-options.ts +++ b/backend/src/entities/user/utils/get-cookie-domain-options.ts @@ -1,7 +1,7 @@ export function getCookieDomainOptions(requestHostname: string): { domain: string } | undefined { - const cookieDomain = process.env.ROCKETADMIN_COOKIE_DOMAIN; - if (cookieDomain && requestHostname?.includes(cookieDomain)) { - return { domain: cookieDomain }; - } - return undefined; + const cookieDomain = process.env.ROCKETADMIN_COOKIE_DOMAIN; + if (cookieDomain && requestHostname?.includes(cookieDomain)) { + return { domain: cookieDomain }; + } + return undefined; } diff --git a/backend/src/entities/user/utils/get-user-intercom-hash.ts b/backend/src/entities/user/utils/get-user-intercom-hash.ts index c8c45a3a8..590762f8b 100644 --- a/backend/src/entities/user/utils/get-user-intercom-hash.ts +++ b/backend/src/entities/user/utils/get-user-intercom-hash.ts @@ -1,6 +1,6 @@ import { Encryptor } from '../../../helpers/encryption/encryptor.js'; export function getUserIntercomHash(userId: string): string | null { - if (!userId) return null; - return Encryptor.getUserIntercomHash(userId); + if (!userId) return null; + return Encryptor.getUserIntercomHash(userId); } diff --git a/backend/src/entities/user/utils/is-jwt-scope-need.util.ts b/backend/src/entities/user/utils/is-jwt-scope-need.util.ts index 6c800d8fb..92fb20bbb 100644 --- a/backend/src/entities/user/utils/is-jwt-scope-need.util.ts +++ b/backend/src/entities/user/utils/is-jwt-scope-need.util.ts @@ -3,9 +3,9 @@ import { JwtScopesEnum } from '../enums/jwt-scopes.enum.js'; import { UserEntity } from '../user.entity.js'; function isJwt2faScopeNeed(user: UserEntity, userCompany: CompanyInfoEntity): boolean { - return userCompany?.is2faEnabled && !user.isOTPEnabled; + return userCompany?.is2faEnabled && !user.isOTPEnabled; } export function get2FaScope(user: UserEntity, userCompany: CompanyInfoEntity): Array { - return isJwt2faScopeNeed(user, userCompany) ? [JwtScopesEnum.TWO_FA_ENABLE] : null; + return isJwt2faScopeNeed(user, userCompany) ? [JwtScopesEnum.TWO_FA_ENABLE] : null; } diff --git a/backend/src/entities/visualizations/dashboard-widget/dashboard-widget.module.ts b/backend/src/entities/visualizations/dashboard-widget/dashboard-widget.module.ts index a8b04e898..6f2970c90 100644 --- a/backend/src/entities/visualizations/dashboard-widget/dashboard-widget.module.ts +++ b/backend/src/entities/visualizations/dashboard-widget/dashboard-widget.module.ts @@ -1,14 +1,14 @@ import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthMiddleware } from '../../../authorization/auth.middleware.js'; import { GlobalDatabaseContext } from '../../../common/application/global-database-context.js'; import { BaseType, UseCaseType } from '../../../common/data-injection.tokens.js'; -import { AuthMiddleware } from '../../../authorization/auth.middleware.js'; -import { UserEntity } from '../../user/user.entity.js'; import { LogOutEntity } from '../../log-out/log-out.entity.js'; +import { UserEntity } from '../../user/user.entity.js'; import { DashboardWidgetController } from './dashboard-widgets.controller.js'; import { CreateDashboardWidgetUseCase } from './use-cases/create-dashboard-widget.use.case.js'; -import { UpdateDashboardWidgetUseCase } from './use-cases/update-dashboard-widget.use.case.js'; import { DeleteDashboardWidgetUseCase } from './use-cases/delete-dashboard-widget.use.case.js'; +import { UpdateDashboardWidgetUseCase } from './use-cases/update-dashboard-widget.use.case.js'; @Module({ imports: [TypeOrmModule.forFeature([UserEntity, LogOutEntity])], diff --git a/backend/src/entities/visualizations/dashboard-widget/dashboard-widgets.controller.ts b/backend/src/entities/visualizations/dashboard-widget/dashboard-widgets.controller.ts index fe3a9a80e..3a446503c 100644 --- a/backend/src/entities/visualizations/dashboard-widget/dashboard-widgets.controller.ts +++ b/backend/src/entities/visualizations/dashboard-widget/dashboard-widgets.controller.ts @@ -14,6 +14,7 @@ import { ApiBearerAuth, ApiBody, ApiOperation, ApiParam, ApiResponse, ApiTags } import { UseCaseType } from '../../../common/data-injection.tokens.js'; import { MasterPassword } from '../../../decorators/master-password.decorator.js'; import { SlugUuid } from '../../../decorators/slug-uuid.decorator.js'; +import { Timeout } from '../../../decorators/timeout.decorator.js'; import { UserId } from '../../../decorators/user-id.decorator.js'; import { InTransactionEnum } from '../../../enums/in-transaction.enum.js'; import { ConnectionEditGuard } from '../../../guards/connection-edit.guard.js'; @@ -29,7 +30,6 @@ import { IDeleteDashboardWidget, IUpdateDashboardWidget, } from './use-cases/dashboard-widget-use-cases.interface.js'; -import { Timeout } from '../../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/visualizations/dashboard-widget/use-cases/create-dashboard-widget.use.case.ts b/backend/src/entities/visualizations/dashboard-widget/use-cases/create-dashboard-widget.use.case.ts index 405f4876e..33d3ef91d 100644 --- a/backend/src/entities/visualizations/dashboard-widget/use-cases/create-dashboard-widget.use.case.ts +++ b/backend/src/entities/visualizations/dashboard-widget/use-cases/create-dashboard-widget.use.case.ts @@ -3,8 +3,8 @@ import AbstractUseCase from '../../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../../common/data-injection.tokens.js'; import { Messages } from '../../../../exceptions/text/messages.js'; -import { CreateDashboardWidgetDs } from '../data-structures/create-dashboard-widget.ds.js'; import { DashboardWidgetEntity } from '../dashboard-widget.entity.js'; +import { CreateDashboardWidgetDs } from '../data-structures/create-dashboard-widget.ds.js'; import { FoundDashboardWidgetDto } from '../dto/found-dashboard-widget.dto.js'; import { buildFoundDashboardWidgetDto } from '../utils/build-found-dashboard-widget-dto.util.js'; import { ICreateDashboardWidget } from './dashboard-widget-use-cases.interface.js'; diff --git a/backend/src/entities/visualizations/dashboard-widget/use-cases/dashboard-widget-use-cases.interface.ts b/backend/src/entities/visualizations/dashboard-widget/use-cases/dashboard-widget-use-cases.interface.ts index 5ae3885c0..fc8f4ed23 100644 --- a/backend/src/entities/visualizations/dashboard-widget/use-cases/dashboard-widget-use-cases.interface.ts +++ b/backend/src/entities/visualizations/dashboard-widget/use-cases/dashboard-widget-use-cases.interface.ts @@ -1,7 +1,7 @@ import { InTransactionEnum } from '../../../../enums/in-transaction.enum.js'; import { CreateDashboardWidgetDs } from '../data-structures/create-dashboard-widget.ds.js'; -import { UpdateDashboardWidgetDs } from '../data-structures/update-dashboard-widget.ds.js'; import { DeleteDashboardWidgetDs } from '../data-structures/delete-dashboard-widget.ds.js'; +import { UpdateDashboardWidgetDs } from '../data-structures/update-dashboard-widget.ds.js'; import { FoundDashboardWidgetDto } from '../dto/found-dashboard-widget.dto.js'; export interface ICreateDashboardWidget { diff --git a/backend/src/entities/visualizations/dashboard/dashboards.controller.ts b/backend/src/entities/visualizations/dashboard/dashboards.controller.ts index fbefb8bad..e981788f5 100644 --- a/backend/src/entities/visualizations/dashboard/dashboards.controller.ts +++ b/backend/src/entities/visualizations/dashboard/dashboards.controller.ts @@ -17,11 +17,12 @@ import { ApiBearerAuth, ApiBody, ApiOperation, ApiParam, ApiResponse, ApiTags } import { UseCaseType } from '../../../common/data-injection.tokens.js'; import { MasterPassword } from '../../../decorators/master-password.decorator.js'; import { SlugUuid } from '../../../decorators/slug-uuid.decorator.js'; +import { Timeout } from '../../../decorators/timeout.decorator.js'; import { UserId } from '../../../decorators/user-id.decorator.js'; import { InTransactionEnum } from '../../../enums/in-transaction.enum.js'; import { Messages } from '../../../exceptions/text/messages.js'; -import { ConnectionReadGuard } from '../../../guards/connection-read.guard.js'; import { ConnectionEditGuard } from '../../../guards/connection-edit.guard.js'; +import { ConnectionReadGuard } from '../../../guards/connection-read.guard.js'; import { SentryInterceptor } from '../../../interceptors/sentry.interceptor.js'; import { CreateDashboardDs } from './data-structures/create-dashboard.ds.js'; import { FindAllDashboardsDs } from './data-structures/find-all-dashboards.ds.js'; @@ -37,7 +38,6 @@ import { IFindDashboard, IUpdateDashboard, } from './use-cases/dashboard-use-cases.interface.js'; -import { Timeout } from '../../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/visualizations/dashboard/dashboards.module.ts b/backend/src/entities/visualizations/dashboard/dashboards.module.ts index 5e888cbc7..2110eaf9c 100644 --- a/backend/src/entities/visualizations/dashboard/dashboards.module.ts +++ b/backend/src/entities/visualizations/dashboard/dashboards.module.ts @@ -1,16 +1,16 @@ import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthMiddleware } from '../../../authorization/auth.middleware.js'; import { GlobalDatabaseContext } from '../../../common/application/global-database-context.js'; import { BaseType, UseCaseType } from '../../../common/data-injection.tokens.js'; -import { AuthMiddleware } from '../../../authorization/auth.middleware.js'; -import { UserEntity } from '../../user/user.entity.js'; import { LogOutEntity } from '../../log-out/log-out.entity.js'; +import { UserEntity } from '../../user/user.entity.js'; import { DashboardController } from './dashboards.controller.js'; import { CreateDashboardUseCase } from './use-cases/create-dashboard.use.case.js'; -import { UpdateDashboardUseCase } from './use-cases/update-dashboard.use.case.js'; -import { FindDashboardUseCase } from './use-cases/find-dashboard.use.case.js'; -import { FindAllDashboardsUseCase } from './use-cases/find-all-dashboards.use.case.js'; import { DeleteDashboardUseCase } from './use-cases/delete-dashboard.use.case.js'; +import { FindAllDashboardsUseCase } from './use-cases/find-all-dashboards.use.case.js'; +import { FindDashboardUseCase } from './use-cases/find-dashboard.use.case.js'; +import { UpdateDashboardUseCase } from './use-cases/update-dashboard.use.case.js'; @Module({ imports: [TypeOrmModule.forFeature([UserEntity, LogOutEntity])], diff --git a/backend/src/entities/visualizations/dashboard/use-cases/create-dashboard.use.case.ts b/backend/src/entities/visualizations/dashboard/use-cases/create-dashboard.use.case.ts index fedc83105..598bd6e08 100644 --- a/backend/src/entities/visualizations/dashboard/use-cases/create-dashboard.use.case.ts +++ b/backend/src/entities/visualizations/dashboard/use-cases/create-dashboard.use.case.ts @@ -3,8 +3,8 @@ import AbstractUseCase from '../../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../../common/data-injection.tokens.js'; import { Messages } from '../../../../exceptions/text/messages.js'; -import { CreateDashboardDs } from '../data-structures/create-dashboard.ds.js'; import { DashboardEntity } from '../dashboard.entity.js'; +import { CreateDashboardDs } from '../data-structures/create-dashboard.ds.js'; import { FoundDashboardDto } from '../dto/found-dashboard.dto.js'; import { buildFoundDashboardDto } from '../utils/build-found-dashboard-dto.util.js'; import { ICreateDashboard } from './dashboard-use-cases.interface.js'; diff --git a/backend/src/entities/visualizations/dashboard/use-cases/dashboard-use-cases.interface.ts b/backend/src/entities/visualizations/dashboard/use-cases/dashboard-use-cases.interface.ts index f7d062c31..31249bf92 100644 --- a/backend/src/entities/visualizations/dashboard/use-cases/dashboard-use-cases.interface.ts +++ b/backend/src/entities/visualizations/dashboard/use-cases/dashboard-use-cases.interface.ts @@ -1,8 +1,8 @@ import { InTransactionEnum } from '../../../../enums/in-transaction.enum.js'; import { CreateDashboardDs } from '../data-structures/create-dashboard.ds.js'; -import { UpdateDashboardDs } from '../data-structures/update-dashboard.ds.js'; -import { FindDashboardDs } from '../data-structures/find-dashboard.ds.js'; import { FindAllDashboardsDs } from '../data-structures/find-all-dashboards.ds.js'; +import { FindDashboardDs } from '../data-structures/find-dashboard.ds.js'; +import { UpdateDashboardDs } from '../data-structures/update-dashboard.ds.js'; import { FoundDashboardDto } from '../dto/found-dashboard.dto.js'; export interface ICreateDashboard { diff --git a/backend/src/entities/visualizations/dashboard/utils/build-found-dashboard-dto.util.ts b/backend/src/entities/visualizations/dashboard/utils/build-found-dashboard-dto.util.ts index d51ba5260..08e6925ad 100644 --- a/backend/src/entities/visualizations/dashboard/utils/build-found-dashboard-dto.util.ts +++ b/backend/src/entities/visualizations/dashboard/utils/build-found-dashboard-dto.util.ts @@ -1,6 +1,6 @@ +import { buildFoundDashboardWidgetDto } from '../../dashboard-widget/utils/build-found-dashboard-widget-dto.util.js'; import { DashboardEntity } from '../dashboard.entity.js'; import { FoundDashboardDto } from '../dto/found-dashboard.dto.js'; -import { buildFoundDashboardWidgetDto } from '../../dashboard-widget/utils/build-found-dashboard-widget-dto.util.js'; export function buildFoundDashboardDto(dashboard: DashboardEntity): FoundDashboardDto { return { diff --git a/backend/src/entities/visualizations/saved-db-query/saved-db-query.controller.ts b/backend/src/entities/visualizations/saved-db-query/saved-db-query.controller.ts index f926e0547..19dccf049 100644 --- a/backend/src/entities/visualizations/saved-db-query/saved-db-query.controller.ts +++ b/backend/src/entities/visualizations/saved-db-query/saved-db-query.controller.ts @@ -18,16 +18,18 @@ import { ApiBearerAuth, ApiBody, ApiOperation, ApiParam, ApiResponse, ApiTags } import { UseCaseType } from '../../../common/data-injection.tokens.js'; import { MasterPassword } from '../../../decorators/master-password.decorator.js'; import { SlugUuid } from '../../../decorators/slug-uuid.decorator.js'; +import { Timeout } from '../../../decorators/timeout.decorator.js'; import { UserId } from '../../../decorators/user-id.decorator.js'; import { InTransactionEnum } from '../../../enums/in-transaction.enum.js'; import { Messages } from '../../../exceptions/text/messages.js'; -import { ConnectionReadGuard } from '../../../guards/connection-read.guard.js'; import { ConnectionEditGuard } from '../../../guards/connection-edit.guard.js'; +import { ConnectionReadGuard } from '../../../guards/connection-read.guard.js'; import { SentryInterceptor } from '../../../interceptors/sentry.interceptor.js'; import { CreateSavedDbQueryDs } from './data-structures/create-saved-db-query.ds.js'; import { ExecuteSavedDbQueryDs } from './data-structures/execute-saved-db-query.ds.js'; import { FindAllSavedDbQueriesDs } from './data-structures/find-all-saved-db-queries.ds.js'; import { FindSavedDbQueryDs } from './data-structures/find-saved-db-query.ds.js'; +import { TestDbQueryDs } from './data-structures/test-db-query.ds.js'; import { UpdateSavedDbQueryDs } from './data-structures/update-saved-db-query.ds.js'; import { CreateSavedDbQueryDto } from './dto/create-saved-db-query.dto.js'; import { ExecuteSavedDbQueryResultDto } from './dto/execute-saved-db-query-result.dto.js'; @@ -44,8 +46,6 @@ import { ITestDbQuery, IUpdateSavedDbQuery, } from './use-cases/saved-db-query-use-cases.interface.js'; -import { TestDbQueryDs } from './data-structures/test-db-query.ds.js'; -import { Timeout } from '../../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/visualizations/saved-db-query/saved-db-query.entity.ts b/backend/src/entities/visualizations/saved-db-query/saved-db-query.entity.ts index 65538fd2f..6d8da4232 100644 --- a/backend/src/entities/visualizations/saved-db-query/saved-db-query.entity.ts +++ b/backend/src/entities/visualizations/saved-db-query/saved-db-query.entity.ts @@ -11,10 +11,10 @@ import { PrimaryGeneratedColumn, Relation, } from 'typeorm'; +import { DashboardWidgetTypeEnum } from '../../../enums/dashboard-widget-type.enum.js'; import { Encryptor } from '../../../helpers/encryption/encryptor.js'; import { ConnectionEntity } from '../../connection/connection.entity.js'; import { DashboardWidgetEntity } from '../dashboard-widget/dashboard-widget.entity.js'; -import { DashboardWidgetTypeEnum } from '../../../enums/dashboard-widget-type.enum.js'; @Entity('saved_db_query') export class SavedDbQueryEntity { diff --git a/backend/src/entities/visualizations/saved-db-query/saved-db-query.module.ts b/backend/src/entities/visualizations/saved-db-query/saved-db-query.module.ts index a5a4f6682..779985e4a 100644 --- a/backend/src/entities/visualizations/saved-db-query/saved-db-query.module.ts +++ b/backend/src/entities/visualizations/saved-db-query/saved-db-query.module.ts @@ -1,18 +1,18 @@ import { MiddlewareConsumer, Module, RequestMethod } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; +import { AuthMiddleware } from '../../../authorization/auth.middleware.js'; import { GlobalDatabaseContext } from '../../../common/application/global-database-context.js'; import { BaseType, UseCaseType } from '../../../common/data-injection.tokens.js'; -import { AuthMiddleware } from '../../../authorization/auth.middleware.js'; -import { UserEntity } from '../../user/user.entity.js'; import { LogOutEntity } from '../../log-out/log-out.entity.js'; +import { UserEntity } from '../../user/user.entity.js'; import { SavedDbQueryController } from './saved-db-query.controller.js'; import { CreateSavedDbQueryUseCase } from './use-cases/create-saved-db-query.use.case.js'; -import { UpdateSavedDbQueryUseCase } from './use-cases/update-saved-db-query.use.case.js'; -import { FindSavedDbQueryUseCase } from './use-cases/find-saved-db-query.use.case.js'; -import { FindAllSavedDbQueriesUseCase } from './use-cases/find-all-saved-db-queries.use.case.js'; import { DeleteSavedDbQueryUseCase } from './use-cases/delete-saved-db-query.use.case.js'; import { ExecuteSavedDbQueryUseCase } from './use-cases/execute-saved-db-query.use.case.js'; +import { FindAllSavedDbQueriesUseCase } from './use-cases/find-all-saved-db-queries.use.case.js'; +import { FindSavedDbQueryUseCase } from './use-cases/find-saved-db-query.use.case.js'; import { TestDbQueryUseCase } from './use-cases/test-db-query.use.case.js'; +import { UpdateSavedDbQueryUseCase } from './use-cases/update-saved-db-query.use.case.js'; @Module({ imports: [TypeOrmModule.forFeature([UserEntity, LogOutEntity])], diff --git a/backend/src/entities/visualizations/saved-db-query/use-cases/create-saved-db-query.use.case.ts b/backend/src/entities/visualizations/saved-db-query/use-cases/create-saved-db-query.use.case.ts index 54ae95ec5..6ef72f488 100644 --- a/backend/src/entities/visualizations/saved-db-query/use-cases/create-saved-db-query.use.case.ts +++ b/backend/src/entities/visualizations/saved-db-query/use-cases/create-saved-db-query.use.case.ts @@ -24,7 +24,8 @@ export class CreateSavedDbQueryUseCase } public async implementation(inputData: CreateSavedDbQueryDs): Promise { - const { connectionId, masterPassword, name, description, widget_type, chart_type, widget_options, query_text } = inputData; + const { connectionId, masterPassword, name, description, widget_type, chart_type, widget_options, query_text } = + inputData; const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( connectionId, diff --git a/backend/src/entities/visualizations/saved-db-query/use-cases/execute-saved-db-query.use.case.ts b/backend/src/entities/visualizations/saved-db-query/use-cases/execute-saved-db-query.use.case.ts index 2e0a38d07..0c4d36311 100644 --- a/backend/src/entities/visualizations/saved-db-query/use-cases/execute-saved-db-query.use.case.ts +++ b/backend/src/entities/visualizations/saved-db-query/use-cases/execute-saved-db-query.use.case.ts @@ -5,11 +5,11 @@ import AbstractUseCase from '../../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../../common/data-injection.tokens.js'; import { Messages } from '../../../../exceptions/text/messages.js'; +import { isConnectionTypeAgent } from '../../../../helpers/is-connection-entity-agent.js'; import { ExecuteSavedDbQueryDs } from '../data-structures/execute-saved-db-query.ds.js'; import { ExecuteSavedDbQueryResultDto } from '../dto/execute-saved-db-query-result.dto.js'; import { validateQuerySafety } from '../utils/check-query-is-safe.util.js'; import { IExecuteSavedDbQuery } from './saved-db-query-use-cases.interface.js'; -import { isConnectionTypeAgent } from '../../../../helpers/is-connection-entity-agent.js'; @Injectable({ scope: Scope.REQUEST }) export class ExecuteSavedDbQueryUseCase diff --git a/backend/src/entities/visualizations/saved-db-query/use-cases/update-saved-db-query.use.case.ts b/backend/src/entities/visualizations/saved-db-query/use-cases/update-saved-db-query.use.case.ts index cafe12d86..7eb25b5d5 100644 --- a/backend/src/entities/visualizations/saved-db-query/use-cases/update-saved-db-query.use.case.ts +++ b/backend/src/entities/visualizations/saved-db-query/use-cases/update-saved-db-query.use.case.ts @@ -6,10 +6,10 @@ import { BaseType } from '../../../../common/data-injection.tokens.js'; import { Messages } from '../../../../exceptions/text/messages.js'; import { UpdateSavedDbQueryDs } from '../data-structures/update-saved-db-query.ds.js'; import { FoundSavedDbQueryDto } from '../dto/found-saved-db-query.dto.js'; +import { SavedDbQueryEntity } from '../saved-db-query.entity.js'; import { buildFoundSavedDbQueryDto } from '../utils/build-found-saved-db-query-dto.util.js'; import { validateQuerySafety } from '../utils/check-query-is-safe.util.js'; import { IUpdateSavedDbQuery } from './saved-db-query-use-cases.interface.js'; -import { SavedDbQueryEntity } from '../saved-db-query.entity.js'; @Injectable({ scope: Scope.REQUEST }) export class UpdateSavedDbQueryUseCase @@ -24,7 +24,17 @@ export class UpdateSavedDbQueryUseCase } public async implementation(inputData: UpdateSavedDbQueryDs): Promise { - const { queryId, connectionId, masterPassword, name, description, widget_type, chart_type, widget_options, query_text } = inputData; + const { + queryId, + connectionId, + masterPassword, + name, + description, + widget_type, + chart_type, + widget_options, + query_text, + } = inputData; const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( connectionId, diff --git a/backend/src/entities/visualizations/saved-db-query/utils/build-found-saved-db-query-dto.util.ts b/backend/src/entities/visualizations/saved-db-query/utils/build-found-saved-db-query-dto.util.ts index a3fc8c49e..c4ed67613 100644 --- a/backend/src/entities/visualizations/saved-db-query/utils/build-found-saved-db-query-dto.util.ts +++ b/backend/src/entities/visualizations/saved-db-query/utils/build-found-saved-db-query-dto.util.ts @@ -1,5 +1,5 @@ -import { SavedDbQueryEntity } from '../saved-db-query.entity.js'; import { FoundSavedDbQueryDto } from '../dto/found-saved-db-query.dto.js'; +import { SavedDbQueryEntity } from '../saved-db-query.entity.js'; export function buildFoundSavedDbQueryDto(entity: SavedDbQueryEntity): FoundSavedDbQueryDto { return { diff --git a/backend/src/entities/widget/application/data-sctructures/create-table-widgets.ds.ts b/backend/src/entities/widget/application/data-sctructures/create-table-widgets.ds.ts index 91acdadd1..c9dd88f33 100644 --- a/backend/src/entities/widget/application/data-sctructures/create-table-widgets.ds.ts +++ b/backend/src/entities/widget/application/data-sctructures/create-table-widgets.ds.ts @@ -1,18 +1,18 @@ import { WidgetTypeEnum } from '../../../../enums/index.js'; export class CreateTableWidgetsDs { - connectionId: string; - masterPwd: string; - tableName: string; - userId: string; - widgets: Array; + connectionId: string; + masterPwd: string; + tableName: string; + userId: string; + widgets: Array; } export class CreateTableWidgetDs { - description: string; - field_name: string; - name: string; - widget_options: string; - widget_params: string; - widget_type: WidgetTypeEnum; + description: string; + field_name: string; + name: string; + widget_options: string; + widget_params: string; + widget_type: WidgetTypeEnum; } diff --git a/backend/src/entities/widget/application/data-sctructures/find-table-widgets.ds.ts b/backend/src/entities/widget/application/data-sctructures/find-table-widgets.ds.ts index 35d3ba4ff..21e7cd581 100644 --- a/backend/src/entities/widget/application/data-sctructures/find-table-widgets.ds.ts +++ b/backend/src/entities/widget/application/data-sctructures/find-table-widgets.ds.ts @@ -1,6 +1,6 @@ export class FindTableWidgetsDs { - connectionId: string; - masterPwd: string; - tableName: string; - userId: string; + connectionId: string; + masterPwd: string; + tableName: string; + userId: string; } diff --git a/backend/src/entities/widget/application/data-sctructures/found-table-widgets.ds.ts b/backend/src/entities/widget/application/data-sctructures/found-table-widgets.ds.ts index 353f711e6..338624936 100644 --- a/backend/src/entities/widget/application/data-sctructures/found-table-widgets.ds.ts +++ b/backend/src/entities/widget/application/data-sctructures/found-table-widgets.ds.ts @@ -1,11 +1,11 @@ import { WidgetTypeEnum } from '../../../../enums/index.js'; export class FoundTableWidgetsDs { - description?: string; - field_name: string; - id: string; - name?: string; - widget_options: string; - widget_params: string; - widget_type?: WidgetTypeEnum; + description?: string; + field_name: string; + id: string; + name?: string; + widget_options: string; + widget_params: string; + widget_type?: WidgetTypeEnum; } diff --git a/backend/src/entities/widget/dto/create-table-widget.dto.ts b/backend/src/entities/widget/dto/create-table-widget.dto.ts index 4e7eef1a6..f88149bec 100644 --- a/backend/src/entities/widget/dto/create-table-widget.dto.ts +++ b/backend/src/entities/widget/dto/create-table-widget.dto.ts @@ -1,42 +1,42 @@ import { ApiProperty } from '@nestjs/swagger'; -import { WidgetTypeEnum } from '../../../enums/index.js'; import { IsArray, IsEnum, IsNotEmpty, IsOptional, IsString, ValidateNested } from 'class-validator'; +import { WidgetTypeEnum } from '../../../enums/index.js'; export class CreateTableWidgetDto { - @ApiProperty() - @IsNotEmpty() - @IsString() - field_name: string; + @ApiProperty() + @IsNotEmpty() + @IsString() + field_name: string; - @ApiProperty({ enum: WidgetTypeEnum }) - @IsOptional() - @IsEnum(WidgetTypeEnum) - widget_type: WidgetTypeEnum; + @ApiProperty({ enum: WidgetTypeEnum }) + @IsOptional() + @IsEnum(WidgetTypeEnum) + widget_type: WidgetTypeEnum; - @ApiProperty() - @IsOptional() - @IsString() - widget_params: string; + @ApiProperty() + @IsOptional() + @IsString() + widget_params: string; - @ApiProperty() - @IsOptional() - @IsString() - widget_options: string; + @ApiProperty() + @IsOptional() + @IsString() + widget_options: string; - @ApiProperty() - @IsOptional() - @IsString() - name: string; + @ApiProperty() + @IsOptional() + @IsString() + name: string; - @ApiProperty() - @IsOptional() - @IsString() - description: string; + @ApiProperty() + @IsOptional() + @IsString() + description: string; } export class CreateOrUpdateTableWidgetsDto { - @ApiProperty() - @IsArray() - @ValidateNested({ each: true }) - widgets: Array; + @ApiProperty() + @IsArray() + @ValidateNested({ each: true }) + widgets: Array; } diff --git a/backend/src/entities/widget/dto/index.ts b/backend/src/entities/widget/dto/index.ts index 42d68a0b7..0c556e2c5 100644 --- a/backend/src/entities/widget/dto/index.ts +++ b/backend/src/entities/widget/dto/index.ts @@ -1,2 +1 @@ -export { CreateTableWidgetDto } from './create-table-widget.dto.js'; -export { CreateOrUpdateTableWidgetsDto } from './create-table-widget.dto.js'; +export { CreateOrUpdateTableWidgetsDto, CreateTableWidgetDto } from './create-table-widget.dto.js'; diff --git a/backend/src/entities/widget/repository/table-widgets-custom-repsitory-extension.ts b/backend/src/entities/widget/repository/table-widgets-custom-repsitory-extension.ts index 5d049dab8..968e291e2 100644 --- a/backend/src/entities/widget/repository/table-widgets-custom-repsitory-extension.ts +++ b/backend/src/entities/widget/repository/table-widgets-custom-repsitory-extension.ts @@ -2,22 +2,22 @@ import { TableSettingsEntity } from '../../table-settings/common-table-settings/ import { TableWidgetEntity } from '../table-widget.entity.js'; export const tableWidgetsCustomRepositoryExtension = { - async findTableWidgets(connectionId: string, tableName: string): Promise> { - const qb = this.manager - .getRepository(TableSettingsEntity) - .createQueryBuilder('tableSettings') - .leftJoinAndSelect('tableSettings.table_widgets', 'table_widgets'); - qb.where('tableSettings.connection_id = :connection_id', { connection_id: connectionId }); - qb.andWhere('tableSettings.table_name = :table_name', { table_name: tableName }); - const result = await qb.getOne(); - return result?.table_widgets ? result?.table_widgets : []; - }, + async findTableWidgets(connectionId: string, tableName: string): Promise> { + const qb = this.manager + .getRepository(TableSettingsEntity) + .createQueryBuilder('tableSettings') + .leftJoinAndSelect('tableSettings.table_widgets', 'table_widgets'); + qb.where('tableSettings.connection_id = :connection_id', { connection_id: connectionId }); + qb.andWhere('tableSettings.table_name = :table_name', { table_name: tableName }); + const result = await qb.getOne(); + return result?.table_widgets ? result?.table_widgets : []; + }, - async saveNewOrUpdatedTableWidget(widget: TableWidgetEntity): Promise { - return await this.save(widget); - }, + async saveNewOrUpdatedTableWidget(widget: TableWidgetEntity): Promise { + return await this.save(widget); + }, - async removeTableWidget(widget: TableWidgetEntity): Promise { - return await this.remove(widget); - }, + async removeTableWidget(widget: TableWidgetEntity): Promise { + return await this.remove(widget); + }, }; diff --git a/backend/src/entities/widget/repository/table-widgets-repository.interface.ts b/backend/src/entities/widget/repository/table-widgets-repository.interface.ts index a52c1f496..dedb953aa 100644 --- a/backend/src/entities/widget/repository/table-widgets-repository.interface.ts +++ b/backend/src/entities/widget/repository/table-widgets-repository.interface.ts @@ -1,9 +1,9 @@ import { TableWidgetEntity } from '../table-widget.entity.js'; export interface ITableWidgetsRepository { - findTableWidgets(connectionId: string, tableName: string): Promise>; + findTableWidgets(connectionId: string, tableName: string): Promise>; - saveNewOrUpdatedTableWidget(widget: TableWidgetEntity): Promise; + saveNewOrUpdatedTableWidget(widget: TableWidgetEntity): Promise; - removeTableWidget(widget: TableWidgetEntity): Promise; + removeTableWidget(widget: TableWidgetEntity): Promise; } diff --git a/backend/src/entities/widget/table-widget.controller.ts b/backend/src/entities/widget/table-widget.controller.ts index d7d7fe83d..e9c274b13 100644 --- a/backend/src/entities/widget/table-widget.controller.ts +++ b/backend/src/entities/widget/table-widget.controller.ts @@ -14,6 +14,7 @@ import { HttpException } from '@nestjs/common/exceptions/http.exception.js'; import { ApiBearerAuth, ApiBody, ApiOperation, ApiQuery, ApiResponse, ApiTags } from '@nestjs/swagger'; import { UseCaseType } from '../../common/data-injection.tokens.js'; import { MasterPassword, QueryTableName, SlugUuid, UserId } from '../../decorators/index.js'; +import { Timeout } from '../../decorators/timeout.decorator.js'; import { InTransactionEnum } from '../../enums/index.js'; import { Messages } from '../../exceptions/text/messages.js'; import { ConnectionEditGuard, ConnectionReadGuard } from '../../guards/index.js'; @@ -24,7 +25,6 @@ import { FoundTableWidgetsDs } from './application/data-sctructures/found-table- import { CreateOrUpdateTableWidgetsDto } from './dto/index.js'; import { TableWidgetRO } from './table-widget.interface.js'; import { ICreateUpdateDeleteTableWidgets, IFindTableWidgets } from './use-cases/table-widgets-use-cases.interface.js'; -import { Timeout } from '../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @Timeout() diff --git a/backend/src/entities/widget/table-widget.interface.ts b/backend/src/entities/widget/table-widget.interface.ts index 268e05c45..e705b297d 100644 --- a/backend/src/entities/widget/table-widget.interface.ts +++ b/backend/src/entities/widget/table-widget.interface.ts @@ -2,26 +2,26 @@ import { ApiProperty } from '@nestjs/swagger'; import { EncryptionAlgorithmEnum, WidgetTypeEnum } from '../../enums/index.js'; export class TableWidgetRO { - @ApiProperty() - id: string; + @ApiProperty() + id: string; - @ApiProperty() - field_name: string; + @ApiProperty() + field_name: string; - @ApiProperty({ enum: WidgetTypeEnum }) - widget_type?: WidgetTypeEnum; + @ApiProperty({ enum: WidgetTypeEnum }) + widget_type?: WidgetTypeEnum; - @ApiProperty() - widget_params: string; + @ApiProperty() + widget_params: string; - @ApiProperty() - name?: string; + @ApiProperty() + name?: string; - @ApiProperty() - description?: string; + @ApiProperty() + description?: string; } export interface IPasswordWidgetParams { - encrypt: boolean; - algorithm: EncryptionAlgorithmEnum; + encrypt: boolean; + algorithm: EncryptionAlgorithmEnum; } diff --git a/backend/src/entities/widget/table-widget.module.ts b/backend/src/entities/widget/table-widget.module.ts index 45c3a713f..bc66a786e 100644 --- a/backend/src/entities/widget/table-widget.module.ts +++ b/backend/src/entities/widget/table-widget.module.ts @@ -11,32 +11,32 @@ import { CreateUpdateDeleteTableWidgetsUseCase } from './use-cases/create-update import { FindTableWidgetsUseCase } from './use-cases/find-table-widgets.use.case.js'; @Module({ - imports: [TypeOrmModule.forFeature([TableWidgetEntity, UserEntity, LogOutEntity])], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.FIND_TABLE_WIDGETS, - useClass: FindTableWidgetsUseCase, - }, - { - provide: UseCaseType.CREATE_UPDATE_DELETE_TABLE_WIDGETS, - useClass: CreateUpdateDeleteTableWidgetsUseCase, - }, - ], + imports: [TypeOrmModule.forFeature([TableWidgetEntity, UserEntity, LogOutEntity])], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.FIND_TABLE_WIDGETS, + useClass: FindTableWidgetsUseCase, + }, + { + provide: UseCaseType.CREATE_UPDATE_DELETE_TABLE_WIDGETS, + useClass: CreateUpdateDeleteTableWidgetsUseCase, + }, + ], - controllers: [TableWidgetController], - exports: [], + controllers: [TableWidgetController], + exports: [], }) export class TableWidgetModule { - public configure(consumer: MiddlewareConsumer): any { - consumer - .apply(AuthMiddleware) - .forRoutes( - { path: '/widgets/:connectionId', method: RequestMethod.GET }, - { path: '/widget/:connectionId', method: RequestMethod.POST }, - ); - } + public configure(consumer: MiddlewareConsumer): any { + consumer + .apply(AuthMiddleware) + .forRoutes( + { path: '/widgets/:connectionId', method: RequestMethod.GET }, + { path: '/widget/:connectionId', method: RequestMethod.POST }, + ); + } } diff --git a/backend/src/entities/widget/use-cases/create-update-delete-table-widgets.use.case.ts b/backend/src/entities/widget/use-cases/create-update-delete-table-widgets.use.case.ts index 1f82255f9..ebe57afc6 100644 --- a/backend/src/entities/widget/use-cases/create-update-delete-table-widgets.use.case.ts +++ b/backend/src/entities/widget/use-cases/create-update-delete-table-widgets.use.case.ts @@ -16,81 +16,79 @@ import { ICreateUpdateDeleteTableWidgets } from './table-widgets-use-cases.inter @Injectable() export class CreateUpdateDeleteTableWidgetsUseCase - extends AbstractUseCase> - implements ICreateUpdateDeleteTableWidgets + extends AbstractUseCase> + implements ICreateUpdateDeleteTableWidgets { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: CreateTableWidgetsDs): Promise> { - const { connectionId, masterPwd, tableName, userId, widgets } = inputData; - const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( - connectionId, - masterPwd, - ); - const errors: Array = await validateCreateWidgetsDs(widgets, userId, foundConnection, tableName, null); - if (errors.length > 0) { - throw new HttpException( - { - message: toPrettyErrorsMsg(errors), - }, - HttpStatus.BAD_REQUEST, - ); - } - let tableSettingToUpdate = await this._dbContext.tableSettingsRepository.findTableSettingsWithTableWidgets( - connectionId, - tableName, - ); + protected async implementation(inputData: CreateTableWidgetsDs): Promise> { + const { connectionId, masterPwd, tableName, userId, widgets } = inputData; + const foundConnection = await this._dbContext.connectionRepository.findAndDecryptConnection( + connectionId, + masterPwd, + ); + const errors: Array = await validateCreateWidgetsDs(widgets, userId, foundConnection, tableName, null); + if (errors.length > 0) { + throw new HttpException( + { + message: toPrettyErrorsMsg(errors), + }, + HttpStatus.BAD_REQUEST, + ); + } + let tableSettingToUpdate = await this._dbContext.tableSettingsRepository.findTableSettingsWithTableWidgets( + connectionId, + tableName, + ); - if (!tableSettingToUpdate) { - const emptyTableSettingsDs = buildEmptyTableSettingsWithEmptyWidgets(connectionId, tableName, userId); - const newTableSettings = buildNewTableSettingsEntity(emptyTableSettingsDs, foundConnection); - tableSettingToUpdate = await this._dbContext.tableSettingsRepository.saveNewOrUpdatedSettings(newTableSettings); - } - const foundTableWidgets = await this._dbContext.tableWidgetsRepository.findTableWidgets(connectionId, tableName); - for (const widget of widgets) { - const availableWidgetIndex = foundTableWidgets.findIndex((w) => { - return widget.field_name === w.field_name; - }); - if (availableWidgetIndex >= 0) { - // eslint-disable-next-line security/detect-object-injection - const updatedWidget = Object.assign(foundTableWidgets[availableWidgetIndex], widget); - await this._dbContext.tableWidgetsRepository.saveNewOrUpdatedTableWidget(updatedWidget); - const widgetIndexInTableSettings = tableSettingToUpdate.table_widgets.findIndex((w) => { - return w.field_name === updatedWidget.field_name; - }); - // eslint-disable-next-line security/detect-object-injection - tableSettingToUpdate.table_widgets[widgetIndexInTableSettings] = updatedWidget; - } else { - const newTableWidget = buildNewTableWidgetEntity(widget); - const createdTableWidget = await this._dbContext.tableWidgetsRepository.saveNewOrUpdatedTableWidget( - newTableWidget, - ); - tableSettingToUpdate.table_widgets.push(createdTableWidget); - } - } - for (const foundTableWidget of foundTableWidgets) { - const findWidgetIndex = widgets.findIndex((widget) => { - return widget.field_name === foundTableWidget.field_name; - }); - if (findWidgetIndex < 0) { - const widgetIndexInTableSettings = tableSettingToUpdate.table_widgets.findIndex((widget) => { - return widget.field_name === foundTableWidget.field_name; - }); - await this._dbContext.tableWidgetsRepository.removeTableWidget(foundTableWidget); - tableSettingToUpdate.table_widgets.splice(widgetIndexInTableSettings, 1); - } - } + if (!tableSettingToUpdate) { + const emptyTableSettingsDs = buildEmptyTableSettingsWithEmptyWidgets(connectionId, tableName, userId); + const newTableSettings = buildNewTableSettingsEntity(emptyTableSettingsDs, foundConnection); + tableSettingToUpdate = await this._dbContext.tableSettingsRepository.saveNewOrUpdatedSettings(newTableSettings); + } + const foundTableWidgets = await this._dbContext.tableWidgetsRepository.findTableWidgets(connectionId, tableName); + for (const widget of widgets) { + const availableWidgetIndex = foundTableWidgets.findIndex((w) => { + return widget.field_name === w.field_name; + }); + if (availableWidgetIndex >= 0) { + // eslint-disable-next-line security/detect-object-injection + const updatedWidget = Object.assign(foundTableWidgets[availableWidgetIndex], widget); + await this._dbContext.tableWidgetsRepository.saveNewOrUpdatedTableWidget(updatedWidget); + const widgetIndexInTableSettings = tableSettingToUpdate.table_widgets.findIndex((w) => { + return w.field_name === updatedWidget.field_name; + }); + // eslint-disable-next-line security/detect-object-injection + tableSettingToUpdate.table_widgets[widgetIndexInTableSettings] = updatedWidget; + } else { + const newTableWidget = buildNewTableWidgetEntity(widget); + const createdTableWidget = + await this._dbContext.tableWidgetsRepository.saveNewOrUpdatedTableWidget(newTableWidget); + tableSettingToUpdate.table_widgets.push(createdTableWidget); + } + } + for (const foundTableWidget of foundTableWidgets) { + const findWidgetIndex = widgets.findIndex((widget) => { + return widget.field_name === foundTableWidget.field_name; + }); + if (findWidgetIndex < 0) { + const widgetIndexInTableSettings = tableSettingToUpdate.table_widgets.findIndex((widget) => { + return widget.field_name === foundTableWidget.field_name; + }); + await this._dbContext.tableWidgetsRepository.removeTableWidget(foundTableWidget); + tableSettingToUpdate.table_widgets.splice(widgetIndexInTableSettings, 1); + } + } - const savedSettings: TableSettingsEntity = await this._dbContext.tableSettingsRepository.saveNewOrUpdatedSettings( - tableSettingToUpdate, - ); - return savedSettings.table_widgets.map((widget) => { - return buildFoundTableWidgetDs(widget); - }); - } + const savedSettings: TableSettingsEntity = + await this._dbContext.tableSettingsRepository.saveNewOrUpdatedSettings(tableSettingToUpdate); + return savedSettings.table_widgets.map((widget) => { + return buildFoundTableWidgetDs(widget); + }); + } } diff --git a/backend/src/entities/widget/use-cases/find-table-widgets.use.case.ts b/backend/src/entities/widget/use-cases/find-table-widgets.use.case.ts index 0d197cc19..13e8aca5e 100644 --- a/backend/src/entities/widget/use-cases/find-table-widgets.use.case.ts +++ b/backend/src/entities/widget/use-cases/find-table-widgets.use.case.ts @@ -12,31 +12,31 @@ import { IFindTableWidgets } from './table-widgets-use-cases.interface.js'; @Injectable() export class FindTableWidgetsUseCase - extends AbstractUseCase> - implements IFindTableWidgets + extends AbstractUseCase> + implements IFindTableWidgets { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: FindTableWidgetsDs): Promise> { - const { connectionId, masterPwd, tableName, userId } = inputData; - const connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, masterPwd); - const tablesInConnection = await findTablesInConnectionUtil(connection, userId, null); - if (!tablesInConnection.includes(tableName)) { - throw new HttpException( - { - message: Messages.TABLE_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - const foundTableWidgets = await this._dbContext.tableWidgetsRepository.findTableWidgets(connectionId, tableName); - return foundTableWidgets.map((widget) => { - return buildFoundTableWidgetDs(widget); - }); - } + protected async implementation(inputData: FindTableWidgetsDs): Promise> { + const { connectionId, masterPwd, tableName, userId } = inputData; + const connection = await this._dbContext.connectionRepository.findAndDecryptConnection(connectionId, masterPwd); + const tablesInConnection = await findTablesInConnectionUtil(connection, userId, null); + if (!tablesInConnection.includes(tableName)) { + throw new HttpException( + { + message: Messages.TABLE_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + const foundTableWidgets = await this._dbContext.tableWidgetsRepository.findTableWidgets(connectionId, tableName); + return foundTableWidgets.map((widget) => { + return buildFoundTableWidgetDs(widget); + }); + } } diff --git a/backend/src/entities/widget/use-cases/table-widgets-use-cases.interface.ts b/backend/src/entities/widget/use-cases/table-widgets-use-cases.interface.ts index c68ba02dc..72521a269 100644 --- a/backend/src/entities/widget/use-cases/table-widgets-use-cases.interface.ts +++ b/backend/src/entities/widget/use-cases/table-widgets-use-cases.interface.ts @@ -1,12 +1,12 @@ +import { InTransactionEnum } from '../../../enums/index.js'; +import { CreateTableWidgetsDs } from '../application/data-sctructures/create-table-widgets.ds.js'; import { FindTableWidgetsDs } from '../application/data-sctructures/find-table-widgets.ds.js'; import { FoundTableWidgetsDs } from '../application/data-sctructures/found-table-widgets.ds.js'; -import { CreateTableWidgetsDs } from '../application/data-sctructures/create-table-widgets.ds.js'; -import { InTransactionEnum } from '../../../enums/index.js'; export interface IFindTableWidgets { - execute(inputData: FindTableWidgetsDs, inTransaction: InTransactionEnum): Promise>; + execute(inputData: FindTableWidgetsDs, inTransaction: InTransactionEnum): Promise>; } export interface ICreateUpdateDeleteTableWidgets { - execute(inputData: CreateTableWidgetsDs, inTransaction: InTransactionEnum): Promise>; + execute(inputData: CreateTableWidgetsDs, inTransaction: InTransactionEnum): Promise>; } diff --git a/backend/src/entities/widget/utils/build-found-table-widget-ds.ts b/backend/src/entities/widget/utils/build-found-table-widget-ds.ts index fb88250be..5e07e14b0 100644 --- a/backend/src/entities/widget/utils/build-found-table-widget-ds.ts +++ b/backend/src/entities/widget/utils/build-found-table-widget-ds.ts @@ -2,14 +2,14 @@ import { FoundTableWidgetsDs } from '../application/data-sctructures/found-table import { TableWidgetEntity } from '../table-widget.entity.js'; export function buildFoundTableWidgetDs(widget: TableWidgetEntity): FoundTableWidgetsDs { - const { description, field_name, id, name, widget_options, widget_params, widget_type } = widget; - return { - description: description, - field_name: field_name, - id: id, - name: name, - widget_options: widget_options ? JSON.stringify(widget_options) : null, - widget_params: widget_params ? widget_params : null, - widget_type: widget_type, - }; + const { description, field_name, id, name, widget_options, widget_params, widget_type } = widget; + return { + description: description, + field_name: field_name, + id: id, + name: name, + widget_options: widget_options ? JSON.stringify(widget_options) : null, + widget_params: widget_params ? widget_params : null, + widget_type: widget_type, + }; } diff --git a/backend/src/entities/widget/utils/build-new-table-widget-entity.ts b/backend/src/entities/widget/utils/build-new-table-widget-entity.ts index 08aecba06..4702a49ff 100644 --- a/backend/src/entities/widget/utils/build-new-table-widget-entity.ts +++ b/backend/src/entities/widget/utils/build-new-table-widget-entity.ts @@ -2,13 +2,13 @@ import { CreateTableWidgetDs } from '../application/data-sctructures/create-tabl import { TableWidgetEntity } from '../table-widget.entity.js'; export function buildNewTableWidgetEntity(widget: CreateTableWidgetDs): TableWidgetEntity { - const { description, field_name, name, widget_options, widget_params, widget_type } = widget; - const newTableWidget = new TableWidgetEntity(); - newTableWidget.description = description; - newTableWidget.field_name = field_name; - newTableWidget.name = name; - newTableWidget.widget_options = widget_options; - newTableWidget.widget_params = widget_params; - newTableWidget.widget_type = widget_type; - return newTableWidget; + const { description, field_name, name, widget_options, widget_params, widget_type } = widget; + const newTableWidget = new TableWidgetEntity(); + newTableWidget.description = description; + newTableWidget.field_name = field_name; + newTableWidget.name = name; + newTableWidget.widget_options = widget_options; + newTableWidget.widget_params = widget_params; + newTableWidget.widget_type = widget_type; + return newTableWidget; } diff --git a/backend/src/entities/widget/utils/validate-create-widgets-ds.ts b/backend/src/entities/widget/utils/validate-create-widgets-ds.ts index 91ffaba7e..8f17fd014 100644 --- a/backend/src/entities/widget/utils/validate-create-widgets-ds.ts +++ b/backend/src/entities/widget/utils/validate-create-widgets-ds.ts @@ -1,16 +1,13 @@ -import JSON5 from "json5"; -import { - EncryptionAlgorithmEnum, - WidgetTypeEnum, -} from "../../../enums/index.js"; -import { Messages } from "../../../exceptions/text/messages.js"; -import { Constants } from "../../../helpers/constants/constants.js"; -import { getPropertyValueByDescriptor } from "../../../helpers/index.js"; -import { ConnectionEntity } from "../../connection/connection.entity.js"; -import { ForeignKeyDSInfo } from "../../table/table-datastructures.js"; -import { findTableFieldsUtil } from "../../table/utils/find-table-fields.util.js"; -import { findTablesInConnectionUtil } from "../../table/utils/find-tables-in-connection.util.js"; -import { CreateTableWidgetDs } from "../application/data-sctructures/create-table-widgets.ds.js"; +import JSON5 from 'json5'; +import { EncryptionAlgorithmEnum, WidgetTypeEnum } from '../../../enums/index.js'; +import { Messages } from '../../../exceptions/text/messages.js'; +import { Constants } from '../../../helpers/constants/constants.js'; +import { getPropertyValueByDescriptor } from '../../../helpers/index.js'; +import { ConnectionEntity } from '../../connection/connection.entity.js'; +import { ForeignKeyDSInfo } from '../../table/table-datastructures.js'; +import { findTableFieldsUtil } from '../../table/utils/find-table-fields.util.js'; +import { findTablesInConnectionUtil } from '../../table/utils/find-tables-in-connection.util.js'; +import { CreateTableWidgetDs } from '../application/data-sctructures/create-table-widgets.ds.js'; export async function validateCreateWidgetsDs( widgetsDS: Array, @@ -20,21 +17,12 @@ export async function validateCreateWidgetsDs( userEmail: string, ): Promise> { const errors = []; - const availableTablesInConnection = await findTablesInConnectionUtil( - connection, - userId, - userEmail, - ); + const availableTablesInConnection = await findTablesInConnectionUtil(connection, userId, userEmail); if (!availableTablesInConnection.includes(tableName)) { errors.push(Messages.TABLE_NOT_FOUND); return errors; } - const availableTableFields = await findTableFieldsUtil( - connection, - tableName, - userId, - userEmail, - ); + const availableTableFields = await findTableFieldsUtil(connection, tableName, userId, userEmail); if (!widgetsDS || !Array.isArray(widgetsDS)) { errors.push(Messages.WIDGETS_PROPERTY_MISSING); return errors; @@ -57,60 +45,39 @@ export async function validateCreateWidgetsDs( // } // } if (widget_type && widget_type === WidgetTypeEnum.Password) { - let widget_params = widgetDS.widget_params as - | string - | Record; - if (typeof widget_params === "string") { + let widget_params = widgetDS.widget_params as string | Record; + if (typeof widget_params === 'string') { widget_params = JSON5.parse(widget_params); } if ( widget_params.algorithm && - !Object.keys(EncryptionAlgorithmEnum).find( - (key) => key === widget_params.algorithm, - ) + !Object.keys(EncryptionAlgorithmEnum).find((key) => key === widget_params.algorithm) ) { - errors.push( - Messages.ENCRYPTION_ALGORITHM_INCORRECT(widget_params.algorithm), - ); + errors.push(Messages.ENCRYPTION_ALGORITHM_INCORRECT(widget_params.algorithm)); } if (widget_params.encrypt === undefined) { - errors.push(Messages.WIDGET_REQUIRED_PARAMETER_MISSING("encrypt")); + errors.push(Messages.WIDGET_REQUIRED_PARAMETER_MISSING('encrypt')); } } if (widget_type && widget_type === WidgetTypeEnum.Foreign_key) { - const widget_params: ForeignKeyDSInfo = JSON5.parse( - widgetDS.widget_params, - ); + const widget_params: ForeignKeyDSInfo = JSON5.parse(widgetDS.widget_params); for (const key in widget_params) { if (!Constants.FOREIGN_KEY_FIELDS.includes(key)) { - errors.push( - Messages.WIDGET_PARAMETER_UNSUPPORTED(key, widgetDS.widget_type), - ); + errors.push(Messages.WIDGET_PARAMETER_UNSUPPORTED(key, widgetDS.widget_type)); continue; } - if ( - !getPropertyValueByDescriptor(widget_params, key) && - key !== "constraint_name" - ) { + if (!getPropertyValueByDescriptor(widget_params, key) && key !== 'constraint_name') { errors.push(Messages.WIDGET_REQUIRED_PARAMETER_MISSING(key)); } } if (errors.length > 0) { return errors; } - if ( - !availableTablesInConnection.includes( - widget_params.referenced_table_name, - ) - ) { - errors.push( - Messages.TABLE_WITH_NAME_NOT_EXISTS( - widget_params.referenced_table_name, - ), - ); + if (!availableTablesInConnection.includes(widget_params.referenced_table_name)) { + errors.push(Messages.TABLE_WITH_NAME_NOT_EXISTS(widget_params.referenced_table_name)); return errors; } const foreignTableFields = await findTableFieldsUtil( @@ -121,10 +88,7 @@ export async function validateCreateWidgetsDs( ); if (!foreignTableFields.includes(widget_params.referenced_column_name)) { errors.push( - Messages.NO_SUCH_FIELD_IN_TABLE( - widget_params.referenced_column_name, - widget_params.referenced_table_name, - ), + Messages.NO_SUCH_FIELD_IN_TABLE(widget_params.referenced_column_name, widget_params.referenced_table_name), ); } } @@ -132,26 +96,16 @@ export async function validateCreateWidgetsDs( if (widget_type && widget_type === WidgetTypeEnum.S3) { const rawParams = widgetDS.widget_params; const widget_params: Record = - typeof rawParams === "string" - ? JSON5.parse(rawParams) - : (rawParams as Record); + typeof rawParams === 'string' ? JSON5.parse(rawParams) : (rawParams as Record); if (!widget_params.bucket) { - errors.push(Messages.WIDGET_REQUIRED_PARAMETER_MISSING("bucket")); + errors.push(Messages.WIDGET_REQUIRED_PARAMETER_MISSING('bucket')); } if (!widget_params.aws_access_key_id_secret_name) { - errors.push( - Messages.WIDGET_REQUIRED_PARAMETER_MISSING( - "aws_access_key_id_secret_name", - ), - ); + errors.push(Messages.WIDGET_REQUIRED_PARAMETER_MISSING('aws_access_key_id_secret_name')); } if (!widget_params.aws_secret_access_key_secret_name) { - errors.push( - Messages.WIDGET_REQUIRED_PARAMETER_MISSING( - "aws_secret_access_key_secret_name", - ), - ); + errors.push(Messages.WIDGET_REQUIRED_PARAMETER_MISSING('aws_secret_access_key_secret_name')); } } } diff --git a/backend/src/enums/access-level.enum.ts b/backend/src/enums/access-level.enum.ts index f49cc60a7..b858ff841 100644 --- a/backend/src/enums/access-level.enum.ts +++ b/backend/src/enums/access-level.enum.ts @@ -1,8 +1,8 @@ export enum AccessLevelEnum { - readonly = 'readonly', - edit = 'edit', - visibility = 'visibility', - add = 'add', - delete = 'delete', - none = 'none', + readonly = 'readonly', + edit = 'edit', + visibility = 'visibility', + add = 'add', + delete = 'delete', + none = 'none', } diff --git a/backend/src/enums/amplitude-event-type.enum.ts b/backend/src/enums/amplitude-event-type.enum.ts index da85878b5..6dd618237 100644 --- a/backend/src/enums/amplitude-event-type.enum.ts +++ b/backend/src/enums/amplitude-event-type.enum.ts @@ -1,27 +1,27 @@ export enum AmplitudeEventTypeEnum { - connectionUpdated = 'Autoadmin_Backend: Connection was updated', - connectionDeleted = 'Autoadmin_Backend: Connection was deleted', - connectionReceived = 'Autoadmin_Backend: Connections received', - connectionUsersReceived = 'Autoadmin_Backend: Connection users list received', - connectionListReceived = 'Autoadmin_Backend: Connections list received', - groupListReceived = 'Autoadmin_Backend: Groups list received', - groupDeleted = 'Autoadmin_Backend: Group deleted', - groupUserAdded = 'Autoadmin_Backend: User added in group', - groupUserRemoved = 'Autoadmin_Backend: User removed from group', - groupUserListReceived = 'Autoadmin_Backend: Group users list received', - tableListReceived = 'Autoadmin_Backend: Tables list received', - tableRowsReceived = 'Autoadmin_Backend: Table rows received', - tableRowReceived = 'Autoadmin_Backend: Table row received', - tableRowAdded = 'Autoadmin_Backend: Table row added', - tableRowDeleted = 'Autoadmin_Backend: Table row deleted', + connectionUpdated = 'Autoadmin_Backend: Connection was updated', + connectionDeleted = 'Autoadmin_Backend: Connection was deleted', + connectionReceived = 'Autoadmin_Backend: Connections received', + connectionUsersReceived = 'Autoadmin_Backend: Connection users list received', + connectionListReceived = 'Autoadmin_Backend: Connections list received', + groupListReceived = 'Autoadmin_Backend: Groups list received', + groupDeleted = 'Autoadmin_Backend: Group deleted', + groupUserAdded = 'Autoadmin_Backend: User added in group', + groupUserRemoved = 'Autoadmin_Backend: User removed from group', + groupUserListReceived = 'Autoadmin_Backend: Group users list received', + tableListReceived = 'Autoadmin_Backend: Tables list received', + tableRowsReceived = 'Autoadmin_Backend: Table rows received', + tableRowReceived = 'Autoadmin_Backend: Table row received', + tableRowAdded = 'Autoadmin_Backend: Table row added', + tableRowDeleted = 'Autoadmin_Backend: Table row deleted', - connectionUpdatedTest = 'Autoadmin_Backend_Test: Connection was updated', - connectionDeletedTest = 'Autoadmin_Backend_Test: Connection was deleted', - connectionReceivedTest = 'Autoadmin_Backend_Test: Connections received', - connectionUsersReceivedTest = 'Autoadmin_Backend_Test: Connection users list received', - tableListReceivedTest = 'Autoadmin_Backend_Test: Tables list received', - tableRowsReceivedTest = 'Autoadmin_Backend_Test: Table rows received', - tableRowReceivedTest = 'Autoadmin_Backend_Test: Table row received', - tableRowAddedTest = 'Autoadmin_Backend_Test: Table row added', - tableRowDeletedTest = 'Autoadmin_Backend_Test: Table row deleted', + connectionUpdatedTest = 'Autoadmin_Backend_Test: Connection was updated', + connectionDeletedTest = 'Autoadmin_Backend_Test: Connection was deleted', + connectionReceivedTest = 'Autoadmin_Backend_Test: Connections received', + connectionUsersReceivedTest = 'Autoadmin_Backend_Test: Connection users list received', + tableListReceivedTest = 'Autoadmin_Backend_Test: Tables list received', + tableRowsReceivedTest = 'Autoadmin_Backend_Test: Table rows received', + tableRowReceivedTest = 'Autoadmin_Backend_Test: Table row received', + tableRowAddedTest = 'Autoadmin_Backend_Test: Table row added', + tableRowDeletedTest = 'Autoadmin_Backend_Test: Table row deleted', } diff --git a/backend/src/enums/encryption-algorithm.enum.ts b/backend/src/enums/encryption-algorithm.enum.ts index b57a720e4..a00b3d946 100644 --- a/backend/src/enums/encryption-algorithm.enum.ts +++ b/backend/src/enums/encryption-algorithm.enum.ts @@ -1,12 +1,12 @@ export enum EncryptionAlgorithmEnum { - sha1 = 'sha1', - sha3 = 'sha3', - sha224 = 'sha224', - sha256 = 'sha256', - sha512 = 'sha512', - sha384 = 'sha384', - bcrypt = 'bcrypt', - scrypt = 'scrypt', - argon2 = 'argon2', - pbkdf2 = 'pbkdf2', + sha1 = 'sha1', + sha3 = 'sha3', + sha224 = 'sha224', + sha256 = 'sha256', + sha512 = 'sha512', + sha384 = 'sha384', + bcrypt = 'bcrypt', + scrypt = 'scrypt', + argon2 = 'argon2', + pbkdf2 = 'pbkdf2', } diff --git a/backend/src/enums/filter-criteria.enum.ts b/backend/src/enums/filter-criteria.enum.ts index 14385e184..85b725133 100644 --- a/backend/src/enums/filter-criteria.enum.ts +++ b/backend/src/enums/filter-criteria.enum.ts @@ -1,12 +1,12 @@ export enum FilterCriteriaEnum { - startswith = 'startswith', - endswith = 'endswith', - gt = 'gt', - lt = 'lt', - lte = 'lte', - gte = 'gte', - contains = 'contains', - icontains = 'icontains', - eq = 'eq', - empty = 'empty' + startswith = 'startswith', + endswith = 'endswith', + gt = 'gt', + lt = 'lt', + lte = 'lte', + gte = 'gte', + contains = 'contains', + icontains = 'icontains', + eq = 'eq', + empty = 'empty', } diff --git a/backend/src/enums/in-transaction.enum.ts b/backend/src/enums/in-transaction.enum.ts index 280993fe3..777e18330 100644 --- a/backend/src/enums/in-transaction.enum.ts +++ b/backend/src/enums/in-transaction.enum.ts @@ -1,4 +1,4 @@ export enum InTransactionEnum { - ON = 'ON', - OFF = 'OFF' + ON = 'ON', + OFF = 'OFF', } diff --git a/backend/src/enums/operation-result-status.enum.ts b/backend/src/enums/operation-result-status.enum.ts index a3f8899b8..d9adc8bbe 100644 --- a/backend/src/enums/operation-result-status.enum.ts +++ b/backend/src/enums/operation-result-status.enum.ts @@ -1,5 +1,5 @@ export enum OperationResultStatusEnum { - successfully = 'successfully', - unsuccessfully = 'unsuccessfully', - unknown = 'unknown', + successfully = 'successfully', + unsuccessfully = 'unsuccessfully', + unknown = 'unknown', } diff --git a/backend/src/enums/permission-type.enum.ts b/backend/src/enums/permission-type.enum.ts index d853e7b01..da8600af7 100644 --- a/backend/src/enums/permission-type.enum.ts +++ b/backend/src/enums/permission-type.enum.ts @@ -1,5 +1,5 @@ export enum PermissionTypeEnum { - Group = 'Group', - Connection = 'Connection', - Table = 'Table', + Group = 'Group', + Connection = 'Connection', + Table = 'Table', } diff --git a/backend/src/enums/query-ordering.enum.ts b/backend/src/enums/query-ordering.enum.ts index 79cedd74e..af68dc388 100644 --- a/backend/src/enums/query-ordering.enum.ts +++ b/backend/src/enums/query-ordering.enum.ts @@ -1,4 +1,4 @@ export enum QueryOrderingEnum { - ASC = 'ASC', - DESC = 'DESC', + ASC = 'ASC', + DESC = 'DESC', } diff --git a/backend/src/enums/subscription-level.enum.ts b/backend/src/enums/subscription-level.enum.ts index ea8109a98..e87274812 100644 --- a/backend/src/enums/subscription-level.enum.ts +++ b/backend/src/enums/subscription-level.enum.ts @@ -1,7 +1,7 @@ export enum SubscriptionLevelEnum { - FREE_PLAN = 'FREE_PLAN', - TEAM_PLAN = 'TEAM_PLAN', - ENTERPRISE_PLAN = 'ENTERPRISE_PLAN', - ANNUAL_TEAM_PLAN = 'ANNUAL_TEAM_PLAN', - ANNUAL_ENTERPRISE_PLAN = 'ANNUAL_ENTERPRISE_PLAN', + FREE_PLAN = 'FREE_PLAN', + TEAM_PLAN = 'TEAM_PLAN', + ENTERPRISE_PLAN = 'ENTERPRISE_PLAN', + ANNUAL_TEAM_PLAN = 'ANNUAL_TEAM_PLAN', + ANNUAL_ENTERPRISE_PLAN = 'ANNUAL_ENTERPRISE_PLAN', } diff --git a/backend/src/enums/table-action-event-enum.ts b/backend/src/enums/table-action-event-enum.ts index b61e56a09..d74c5bffe 100644 --- a/backend/src/enums/table-action-event-enum.ts +++ b/backend/src/enums/table-action-event-enum.ts @@ -1,6 +1,6 @@ export enum TableActionEventEnum { - ADD_ROW = 'ADD_ROW', - UPDATE_ROW = 'UPDATE_ROW', - DELETE_ROW = 'DELETE_ROW', - CUSTOM = 'CUSTOM', + ADD_ROW = 'ADD_ROW', + UPDATE_ROW = 'UPDATE_ROW', + DELETE_ROW = 'DELETE_ROW', + CUSTOM = 'CUSTOM', } diff --git a/backend/src/enums/table-action-method-enum.ts b/backend/src/enums/table-action-method-enum.ts index b954fd4c7..518a6da48 100644 --- a/backend/src/enums/table-action-method-enum.ts +++ b/backend/src/enums/table-action-method-enum.ts @@ -1,6 +1,6 @@ export enum TableActionMethodEnum { - ZAPIER = 'ZAPIER', - EMAIL = 'EMAIL', - SLACK = 'SLACK', - URL = 'URL', + ZAPIER = 'ZAPIER', + EMAIL = 'EMAIL', + SLACK = 'SLACK', + URL = 'URL', } diff --git a/backend/src/enums/table-action-type.enum.ts b/backend/src/enums/table-action-type.enum.ts index 9d002be4a..a5131a03a 100644 --- a/backend/src/enums/table-action-type.enum.ts +++ b/backend/src/enums/table-action-type.enum.ts @@ -1,4 +1,4 @@ export enum TableActionTypeEnum { - single = 'single', - multiple = 'multiple', + single = 'single', + multiple = 'multiple', } diff --git a/backend/src/enums/user-action.enum.ts b/backend/src/enums/user-action.enum.ts index 05bc85274..0beaffd07 100644 --- a/backend/src/enums/user-action.enum.ts +++ b/backend/src/enums/user-action.enum.ts @@ -1,4 +1,4 @@ export enum UserActionEnum { - CONNECTION_CREATION_FINISHED = 'CONNECTION_CREATION_FINISHED', - CONNECTION_CREATION_NOT_FINISHED = 'CONNECTION_CREATION_NOT_FINISHED', + CONNECTION_CREATION_FINISHED = 'CONNECTION_CREATION_FINISHED', + CONNECTION_CREATION_NOT_FINISHED = 'CONNECTION_CREATION_NOT_FINISHED', } diff --git a/backend/src/enums/widget-type.enum.ts b/backend/src/enums/widget-type.enum.ts index 2c112d75e..121da11c6 100644 --- a/backend/src/enums/widget-type.enum.ts +++ b/backend/src/enums/widget-type.enum.ts @@ -1,25 +1,25 @@ export enum WidgetTypeEnum { - Password = 'Password', - Boolean = 'Boolean', - Date = 'Date', - Time = 'Time', - DateTime = 'DateTime', - JSON = 'JSON', - Textarea = 'Textarea', - String = 'String', - Readonly = 'Readonly', - Number = 'Number', - Select = 'Select', - UUID = 'UUID', - Foreign_key = 'Foreign_key', - File = 'File', - Image = 'Image', - URL = 'URL', - Code = 'Code', - Phone = 'Phone', - Country = 'Country', - Color = 'Color', - Range = 'Range', - Timezone = 'Timezone', - S3 = 'S3', + Password = 'Password', + Boolean = 'Boolean', + Date = 'Date', + Time = 'Time', + DateTime = 'DateTime', + JSON = 'JSON', + Textarea = 'Textarea', + String = 'String', + Readonly = 'Readonly', + Number = 'Number', + Select = 'Select', + UUID = 'UUID', + Foreign_key = 'Foreign_key', + File = 'File', + Image = 'Image', + URL = 'URL', + Code = 'Code', + Phone = 'Phone', + Country = 'Country', + Color = 'Color', + Range = 'Range', + Timezone = 'Timezone', + S3 = 'S3', } diff --git a/backend/src/exceptions/all-exceptions.filter.ts b/backend/src/exceptions/all-exceptions.filter.ts index 5fed34334..adb4b49df 100644 --- a/backend/src/exceptions/all-exceptions.filter.ts +++ b/backend/src/exceptions/all-exceptions.filter.ts @@ -1,65 +1,64 @@ import { ArgumentsHost, Catch, ExceptionFilter, HttpException, HttpStatus } from '@nestjs/common'; - -import { processExceptionMessage } from './utils/process-exception-message.js'; import Sentry from '@sentry/minimal'; -import { Messages } from './text/messages.js'; import { WinstonLogger } from '../entities/logging/winston-logger.js'; +import { Messages } from './text/messages.js'; +import { processExceptionMessage } from './utils/process-exception-message.js'; export type ExceptionType = 'no_master_key' | 'invalid_master_key' | 'query_timeout'; @Catch() export class AllExceptionsFilter implements ExceptionFilter { - constructor(private readonly logger: WinstonLogger) {} - async catch(exception: any, host: ArgumentsHost) { - const ctx = host.switchToHttp(); - const response = ctx.getResponse(); - const request = ctx.getRequest(); - let text = exception.message; - text = processExceptionMessage(text); - const type = exception?.response?.type; - const originalMessage = exception?.originalMessage; - const internalCode = exception?.internalCode; - const status = exception instanceof HttpException ? exception.getStatus() : HttpStatus.INTERNAL_SERVER_ERROR; - const sentryContextObject = { - extra: { - original_exception_message: originalMessage, - message_to_user: text ? text : 'Something went wrong', - path: request.url, - exception_status_code: status, - }, - }; - Sentry.captureException(exception, sentryContextObject); + constructor(private readonly logger: WinstonLogger) {} + async catch(exception: any, host: ArgumentsHost) { + const ctx = host.switchToHttp(); + const response = ctx.getResponse(); + const request = ctx.getRequest(); + let text = exception.message; + text = processExceptionMessage(text); + const type = exception?.response?.type; + const originalMessage = exception?.originalMessage; + const internalCode = exception?.internalCode; + const status = exception instanceof HttpException ? exception.getStatus() : HttpStatus.INTERNAL_SERVER_ERROR; + const sentryContextObject = { + extra: { + original_exception_message: originalMessage, + message_to_user: text ? text : 'Something went wrong', + path: request.url, + exception_status_code: status, + }, + }; + Sentry.captureException(exception, sentryContextObject); - if (status === 500 || status === 408) { - this.logger.error(exception); - } + if (status === 500 || status === 408) { + this.logger.error(exception); + } - const customExceptionType = this.getErrorType(text); + const customExceptionType = this.getErrorType(text); - response.status(status).json({ - message: text ? text : 'Something went wrong', - type: type ? type : customExceptionType, - statusCode: status, - timestamp: new Date().toISOString(), - path: request.url, - originalMessage: originalMessage, - internalCode: internalCode, - }); - } + response.status(status).json({ + message: text ? text : 'Something went wrong', + type: type ? type : customExceptionType, + statusCode: status, + timestamp: new Date().toISOString(), + path: request.url, + originalMessage: originalMessage, + internalCode: internalCode, + }); + } - private getErrorType(errorText: string): ExceptionType | undefined { - const ifErrorMasterPwdMissing = errorText === Messages.MASTER_PASSWORD_MISSING; - const ifErrorMasterPwdIncorrect = errorText === Messages.MASTER_PASSWORD_INCORRECT; - const ifTimeOutError = errorText.toLowerCase().includes('timeout'); + private getErrorType(errorText: string): ExceptionType | undefined { + const ifErrorMasterPwdMissing = errorText === Messages.MASTER_PASSWORD_MISSING; + const ifErrorMasterPwdIncorrect = errorText === Messages.MASTER_PASSWORD_INCORRECT; + const ifTimeOutError = errorText.toLowerCase().includes('timeout'); - if (ifErrorMasterPwdMissing) { - return 'no_master_key'; - } - if (ifErrorMasterPwdIncorrect) { - return 'invalid_master_key'; - } - if (ifTimeOutError) { - return 'query_timeout'; - } - return undefined; - } + if (ifErrorMasterPwdMissing) { + return 'no_master_key'; + } + if (ifErrorMasterPwdIncorrect) { + return 'invalid_master_key'; + } + if (ifTimeOutError) { + return 'query_timeout'; + } + return undefined; + } } diff --git a/backend/src/exceptions/custom-exceptions/custom-exceptions-internal-codes/exceptions-internal-codes.ts b/backend/src/exceptions/custom-exceptions/custom-exceptions-internal-codes/exceptions-internal-codes.ts index f7b6b56f5..7136e7747 100644 --- a/backend/src/exceptions/custom-exceptions/custom-exceptions-internal-codes/exceptions-internal-codes.ts +++ b/backend/src/exceptions/custom-exceptions/custom-exceptions-internal-codes/exceptions-internal-codes.ts @@ -1,9 +1,8 @@ export enum ExceptionsInternalCodes { - UNKNOWN_SQL_EXCEPTION = 1000, - GET_TABLE_STRUCTURE_EXCEPTION = 1003, - GET_ROW_BY_PRIMARY_KEY_EXCEPTION = 1004, - GET_TABLES_EXCEPTION = 1005, - GET_TABLE_ROWS_EXCEPTION = 1006, - VALIDATOR_EXCEPTION = 1007, + UNKNOWN_SQL_EXCEPTION = 1000, + GET_TABLE_STRUCTURE_EXCEPTION = 1003, + GET_ROW_BY_PRIMARY_KEY_EXCEPTION = 1004, + GET_TABLES_EXCEPTION = 1005, + GET_TABLE_ROWS_EXCEPTION = 1006, + VALIDATOR_EXCEPTION = 1007, } - diff --git a/backend/src/exceptions/custom-exceptions/delete-row-exception.ts b/backend/src/exceptions/custom-exceptions/delete-row-exception.ts index 603e1d068..70efae676 100644 --- a/backend/src/exceptions/custom-exceptions/delete-row-exception.ts +++ b/backend/src/exceptions/custom-exceptions/delete-row-exception.ts @@ -3,12 +3,12 @@ import { ExceptionsInternalCodes } from './custom-exceptions-internal-codes/exce import { ErrorsMessages } from './messages/custom-errors-messages.js'; export class DeleteRowException extends HttpException { - public readonly originalMessage: string; - public readonly internalCode: ExceptionsInternalCodes; - constructor(originalMessage: string) { - const readableMessage = ErrorsMessages.FAILED_TO_DELETE_ROW; - super(readableMessage, HttpStatus.INTERNAL_SERVER_ERROR); - this.originalMessage = originalMessage; - this.internalCode = ExceptionsInternalCodes.UNKNOWN_SQL_EXCEPTION; - } + public readonly originalMessage: string; + public readonly internalCode: ExceptionsInternalCodes; + constructor(originalMessage: string) { + const readableMessage = ErrorsMessages.FAILED_TO_DELETE_ROW; + super(readableMessage, HttpStatus.INTERNAL_SERVER_ERROR); + this.originalMessage = originalMessage; + this.internalCode = ExceptionsInternalCodes.UNKNOWN_SQL_EXCEPTION; + } } diff --git a/backend/src/exceptions/custom-exceptions/exception-operation.ts b/backend/src/exceptions/custom-exceptions/exception-operation.ts index 977496227..64c26d658 100644 --- a/backend/src/exceptions/custom-exceptions/exception-operation.ts +++ b/backend/src/exceptions/custom-exceptions/exception-operation.ts @@ -1,10 +1,10 @@ export const ExceptionOperations = { - FAILED_TO_GET_TABLES: `Failed to get tables from database.`, - FAILED_TO_DELETE_ROW_FROM_TABLE: `Failed to delete row from table.`, - FAILED_TO_DELETE_ROWS_FROM_TABLE: `Failed to delete rows from table.`, - FAILED_TO_UPDATE_ROW_IN_TABLE: `Failed to update row in table.`, - FAILED_TO_UPDATE_ROWS_IN_TABLE: `Failed to update rows in table.`, - FAILED_TO_GET_ROW_BY_PRIMARY_KEY: `Failed to get row by primary key.`, - FAILED_TO_GET_ROWS_FROM_TABLE: `Failed to get rows from table.`, - FAILED_TO_GET_TABLE_STRUCTURE: `Failed to get table structure.`, + FAILED_TO_GET_TABLES: `Failed to get tables from database.`, + FAILED_TO_DELETE_ROW_FROM_TABLE: `Failed to delete row from table.`, + FAILED_TO_DELETE_ROWS_FROM_TABLE: `Failed to delete rows from table.`, + FAILED_TO_UPDATE_ROW_IN_TABLE: `Failed to update row in table.`, + FAILED_TO_UPDATE_ROWS_IN_TABLE: `Failed to update rows in table.`, + FAILED_TO_GET_ROW_BY_PRIMARY_KEY: `Failed to get row by primary key.`, + FAILED_TO_GET_ROWS_FROM_TABLE: `Failed to get rows from table.`, + FAILED_TO_GET_TABLE_STRUCTURE: `Failed to get table structure.`, }; diff --git a/backend/src/exceptions/custom-exceptions/messages/custom-errors-messages.ts b/backend/src/exceptions/custom-exceptions/messages/custom-errors-messages.ts index d2e54aa6f..5c17bfa81 100644 --- a/backend/src/exceptions/custom-exceptions/messages/custom-errors-messages.ts +++ b/backend/src/exceptions/custom-exceptions/messages/custom-errors-messages.ts @@ -1,9 +1,9 @@ export const ErrorsMessages = { - FAILED_TO_DELETE_ROW: `Failed to delete row. Please try again later or contact our support team.`, - FAILED_TO_GET_TABLE_STRUCTURE: `Failed to get table structure. Please try again later or contact our support team.`, - FAILED_TO_GET_TABLE_PRIMARY_COLUMNS: `Failed to get table primary columns. Please try again later or contact our support team.`, - FAILED_TO_GET_ROW: `Failed to get row. Please try again later or contact our support team.`, - FAILED_TO_GET_TABLES: `Failed to get tables. Please try again later or contact our support team.`, - FAILED_TO_GET_TABLE_ROWS: `Failed to get table rows. Please try again later or contact our support team.`, - VALIDATION_FAILED:`Request data is not valid. Please check your request and try again.`, -} \ No newline at end of file + FAILED_TO_DELETE_ROW: `Failed to delete row. Please try again later or contact our support team.`, + FAILED_TO_GET_TABLE_STRUCTURE: `Failed to get table structure. Please try again later or contact our support team.`, + FAILED_TO_GET_TABLE_PRIMARY_COLUMNS: `Failed to get table primary columns. Please try again later or contact our support team.`, + FAILED_TO_GET_ROW: `Failed to get row. Please try again later or contact our support team.`, + FAILED_TO_GET_TABLES: `Failed to get tables. Please try again later or contact our support team.`, + FAILED_TO_GET_TABLE_ROWS: `Failed to get table rows. Please try again later or contact our support team.`, + VALIDATION_FAILED: `Request data is not valid. Please check your request and try again.`, +}; diff --git a/backend/src/exceptions/custom-exceptions/non-available-in-free-plan-exception.ts b/backend/src/exceptions/custom-exceptions/non-available-in-free-plan-exception.ts index 3c3869c25..754757eac 100644 --- a/backend/src/exceptions/custom-exceptions/non-available-in-free-plan-exception.ts +++ b/backend/src/exceptions/custom-exceptions/non-available-in-free-plan-exception.ts @@ -2,7 +2,7 @@ import { HttpException, HttpStatus } from '@nestjs/common'; import { Messages } from '../text/messages.js'; export class NonAvailableInFreePlanException extends HttpException { - constructor(message: string = Messages.FEATURE_NON_AVAILABLE_IN_FREE_PLAN) { - super(message, HttpStatus.PAYMENT_REQUIRED); - } + constructor(message: string = Messages.FEATURE_NON_AVAILABLE_IN_FREE_PLAN) { + super(message, HttpStatus.PAYMENT_REQUIRED); + } } diff --git a/backend/src/exceptions/custom-exceptions/unknown-sql-exception.ts b/backend/src/exceptions/custom-exceptions/unknown-sql-exception.ts index 9685ec294..ba9129958 100644 --- a/backend/src/exceptions/custom-exceptions/unknown-sql-exception.ts +++ b/backend/src/exceptions/custom-exceptions/unknown-sql-exception.ts @@ -2,19 +2,19 @@ import { HttpException, HttpStatus } from '@nestjs/common'; import { ExceptionsInternalCodes } from './custom-exceptions-internal-codes/exceptions-internal-codes.js'; export class UnknownSQLException extends HttpException { - public readonly originalMessage: string; - public readonly internalCode: ExceptionsInternalCodes; - constructor(originalMessage: string, operationType?: string) { - const additionalMessage = isAgentNoDataError(originalMessage) ? 'No data returned from agent': `It seems like something went wrong while processing your query. Please try again later or contact our support team.`; - const readableMessage = `${ - operationType ? `${operationType} ` : '' - }${additionalMessage}`; - super(readableMessage, HttpStatus.INTERNAL_SERVER_ERROR); - this.originalMessage = originalMessage; - this.internalCode = ExceptionsInternalCodes.UNKNOWN_SQL_EXCEPTION; - } + public readonly originalMessage: string; + public readonly internalCode: ExceptionsInternalCodes; + constructor(originalMessage: string, operationType?: string) { + const additionalMessage = isAgentNoDataError(originalMessage) + ? 'No data returned from agent' + : `It seems like something went wrong while processing your query. Please try again later or contact our support team.`; + const readableMessage = `${operationType ? `${operationType} ` : ''}${additionalMessage}`; + super(readableMessage, HttpStatus.INTERNAL_SERVER_ERROR); + this.originalMessage = originalMessage; + this.internalCode = ExceptionsInternalCodes.UNKNOWN_SQL_EXCEPTION; + } } function isAgentNoDataError(originalMessage: string): boolean { - return originalMessage === 'No data returned from agent'; -} \ No newline at end of file + return originalMessage === 'No data returned from agent'; +} diff --git a/backend/src/exceptions/custom-exceptions/validation-exception.ts b/backend/src/exceptions/custom-exceptions/validation-exception.ts index 1ed547c94..0d73bfbb1 100644 --- a/backend/src/exceptions/custom-exceptions/validation-exception.ts +++ b/backend/src/exceptions/custom-exceptions/validation-exception.ts @@ -1,22 +1,22 @@ import { HttpException, HttpStatus } from '@nestjs/common'; -import { ExceptionsInternalCodes } from './custom-exceptions-internal-codes/exceptions-internal-codes.js'; import { ValidationError } from 'class-validator'; +import { ExceptionsInternalCodes } from './custom-exceptions-internal-codes/exceptions-internal-codes.js'; export class ValidationException extends HttpException { - public readonly originalMessage: string; - public readonly internalCode: ExceptionsInternalCodes; + public readonly originalMessage: string; + public readonly internalCode: ExceptionsInternalCodes; - constructor(originalMessage: string | ValidationError[]) { - if (Array.isArray(originalMessage)) { - originalMessage = originalMessage - .map((error) => { - return `Property "${error.property}" validation failed with following errors: ${Object.values( - error.constraints, - ).join(', ')}`; - }) - .join('.\n'); - } - super(originalMessage, HttpStatus.BAD_REQUEST); - this.internalCode = ExceptionsInternalCodes.VALIDATOR_EXCEPTION; - } + constructor(originalMessage: string | ValidationError[]) { + if (Array.isArray(originalMessage)) { + originalMessage = originalMessage + .map((error) => { + return `Property "${error.property}" validation failed with following errors: ${Object.values( + error.constraints, + ).join(', ')}`; + }) + .join('.\n'); + } + super(originalMessage, HttpStatus.BAD_REQUEST); + this.internalCode = ExceptionsInternalCodes.VALIDATOR_EXCEPTION; + } } diff --git a/backend/src/exceptions/utils/process-exception-message.ts b/backend/src/exceptions/utils/process-exception-message.ts index 67bffe60d..aab83a569 100644 --- a/backend/src/exceptions/utils/process-exception-message.ts +++ b/backend/src/exceptions/utils/process-exception-message.ts @@ -2,35 +2,35 @@ import { PROCESSING_MESSAGES_FIND } from './processing-messages-find.js'; import { PROCESSING_MESSAGES_REPLACE } from './processing-messages-replace.js'; export function processExceptionMessage(message: string): string { - const msgInLowerCase = message.toLowerCase(); - switch (true) { - case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.ETIMEDOUT) && - msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.AMAZON_HOSTNAME): - return PROCESSING_MESSAGES_REPLACE.ALLOW_CONNECTIONS; - case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.ETIMEDOUT): - case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.getaddrinfo_ENOTFOUND): - case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.ECONNREFUSED): - case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.EHOSTUNREACH): - case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.ECONNRESET): - case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.SERVER_CLOSED): - return PROCESSING_MESSAGES_REPLACE.getaddrinfo_ENOTFOUND; - case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.ORA_02292): - return PROCESSING_MESSAGES_REPLACE.ORA_02292; - case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.NO_PGHBA_ENTRY): - return PROCESSING_MESSAGES_REPLACE.NO_PGHBA_ENTRY; - case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.UPDATE_COMMAND_DENIED): - return PROCESSING_MESSAGES_REPLACE.UPDATE_COMMAND_DENIED; - case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.VIOLATES_FOREIGN_CONSTRAINT_PG): - return PROCESSING_MESSAGES_REPLACE.VIOLATES_FOREIGN_CONSTRAINT_PG(msgInLowerCase); - case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.VIOLATES_FOREIGN_CONSTRAINT_MYSQL): - return PROCESSING_MESSAGES_REPLACE.VIOLATES_FOREIGN_CONSTRAINT_MYSQL(msgInLowerCase); - case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.VIOLATES_FOREIGN_CONSTRAINT_MSSQL): - return PROCESSING_MESSAGES_REPLACE.VIOLATES_FOREIGN_CONSTRAINT_MSSQL(msgInLowerCase); - case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.SELECT_COMMAND_DENIED_MYSQL): - return PROCESSING_MESSAGES_REPLACE.SELECT_COMMAND_DENIED_MYSQL(msgInLowerCase); - case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.Malformed_UTF_data): - return PROCESSING_MESSAGES_REPLACE.Malformed_UTF_data; - default: - return message; - } + const msgInLowerCase = message.toLowerCase(); + switch (true) { + case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.ETIMEDOUT) && + msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.AMAZON_HOSTNAME): + return PROCESSING_MESSAGES_REPLACE.ALLOW_CONNECTIONS; + case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.ETIMEDOUT): + case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.getaddrinfo_ENOTFOUND): + case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.ECONNREFUSED): + case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.EHOSTUNREACH): + case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.ECONNRESET): + case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.SERVER_CLOSED): + return PROCESSING_MESSAGES_REPLACE.getaddrinfo_ENOTFOUND; + case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.ORA_02292): + return PROCESSING_MESSAGES_REPLACE.ORA_02292; + case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.NO_PGHBA_ENTRY): + return PROCESSING_MESSAGES_REPLACE.NO_PGHBA_ENTRY; + case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.UPDATE_COMMAND_DENIED): + return PROCESSING_MESSAGES_REPLACE.UPDATE_COMMAND_DENIED; + case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.VIOLATES_FOREIGN_CONSTRAINT_PG): + return PROCESSING_MESSAGES_REPLACE.VIOLATES_FOREIGN_CONSTRAINT_PG(msgInLowerCase); + case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.VIOLATES_FOREIGN_CONSTRAINT_MYSQL): + return PROCESSING_MESSAGES_REPLACE.VIOLATES_FOREIGN_CONSTRAINT_MYSQL(msgInLowerCase); + case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.VIOLATES_FOREIGN_CONSTRAINT_MSSQL): + return PROCESSING_MESSAGES_REPLACE.VIOLATES_FOREIGN_CONSTRAINT_MSSQL(msgInLowerCase); + case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.SELECT_COMMAND_DENIED_MYSQL): + return PROCESSING_MESSAGES_REPLACE.SELECT_COMMAND_DENIED_MYSQL(msgInLowerCase); + case msgInLowerCase.includes(PROCESSING_MESSAGES_FIND.Malformed_UTF_data): + return PROCESSING_MESSAGES_REPLACE.Malformed_UTF_data; + default: + return message; + } } diff --git a/backend/src/exceptions/utils/processing-messages-find.ts b/backend/src/exceptions/utils/processing-messages-find.ts index 0a0cc6e9a..e321baa7f 100644 --- a/backend/src/exceptions/utils/processing-messages-find.ts +++ b/backend/src/exceptions/utils/processing-messages-find.ts @@ -1,17 +1,17 @@ export const PROCESSING_MESSAGES_FIND = { - getaddrinfo_ENOTFOUND: `enotfound`, - ORA_02292: 'ora-02292', - ETIMEDOUT: 'etimedout', - AMAZON_HOSTNAME: '.amazonaws.com', - ECONNREFUSED: 'econnrefused', - EHOSTUNREACH: 'ehostunreach', - ECONNRESET: 'econnreset', - SERVER_CLOSED: 'server closed', - NO_PGHBA_ENTRY: 'no pg_hba.conf entry for host', - UPDATE_COMMAND_DENIED: 'update command denied to user', - VIOLATES_FOREIGN_CONSTRAINT_PG: 'violates foreign key constraint', - VIOLATES_FOREIGN_CONSTRAINT_MYSQL: 'cannot delete or update a parent row: a foreign key constraint fails', - VIOLATES_FOREIGN_CONSTRAINT_MSSQL: 'statement conflicted with the reference constraint', - SELECT_COMMAND_DENIED_MYSQL: 'select command denied to user', - Malformed_UTF_data: 'malformed utf-8 data', + getaddrinfo_ENOTFOUND: `enotfound`, + ORA_02292: 'ora-02292', + ETIMEDOUT: 'etimedout', + AMAZON_HOSTNAME: '.amazonaws.com', + ECONNREFUSED: 'econnrefused', + EHOSTUNREACH: 'ehostunreach', + ECONNRESET: 'econnreset', + SERVER_CLOSED: 'server closed', + NO_PGHBA_ENTRY: 'no pg_hba.conf entry for host', + UPDATE_COMMAND_DENIED: 'update command denied to user', + VIOLATES_FOREIGN_CONSTRAINT_PG: 'violates foreign key constraint', + VIOLATES_FOREIGN_CONSTRAINT_MYSQL: 'cannot delete or update a parent row: a foreign key constraint fails', + VIOLATES_FOREIGN_CONSTRAINT_MSSQL: 'statement conflicted with the reference constraint', + SELECT_COMMAND_DENIED_MYSQL: 'select command denied to user', + Malformed_UTF_data: 'malformed utf-8 data', }; diff --git a/backend/src/exceptions/utils/processing-messages-replace.ts b/backend/src/exceptions/utils/processing-messages-replace.ts index 89a26a0fe..bef7270bc 100644 --- a/backend/src/exceptions/utils/processing-messages-replace.ts +++ b/backend/src/exceptions/utils/processing-messages-replace.ts @@ -1,63 +1,63 @@ export const PROCESSING_MESSAGES_REPLACE = { - getaddrinfo_ENOTFOUND: - 'Client was not able to connect to this address. Please check the hostname and port, ' + - 'and make sure our servers are able to access your database. We use IP address 18.221.81.73 for all outbound requests.', - ORA_02292: 'You tried to change a record in a table that is referenced by a record in a child table ', - ALLOW_CONNECTIONS: - 'Client was not able to connect to address. Please allow external connections to your database ' + - 'or use agent connection.', - UPDATE_COMMAND_DENIED: `No permission to update record. Please ask your system administator to grant you access in the database`, - NO_PGHBA_ENTRY: `Please add this line to pg_hba.conf: all 18.221.81.73/32 md5`, - VIOLATES_FOREIGN_CONSTRAINT_PG: (originalMessage: string): string => { - try { - const words = originalMessage.split(' '); - const updateWordIndex = words.indexOf('update'); - const firstTableName = words.at(updateWordIndex + 5); - const violatesWordIndex = words.indexOf('violates'); - const secondTableName = words.at(violatesWordIndex + 7); - const message = ` + getaddrinfo_ENOTFOUND: + 'Client was not able to connect to this address. Please check the hostname and port, ' + + 'and make sure our servers are able to access your database. We use IP address 18.221.81.73 for all outbound requests.', + ORA_02292: 'You tried to change a record in a table that is referenced by a record in a child table ', + ALLOW_CONNECTIONS: + 'Client was not able to connect to address. Please allow external connections to your database ' + + 'or use agent connection.', + UPDATE_COMMAND_DENIED: `No permission to update record. Please ask your system administator to grant you access in the database`, + NO_PGHBA_ENTRY: `Please add this line to pg_hba.conf: all 18.221.81.73/32 md5`, + VIOLATES_FOREIGN_CONSTRAINT_PG: (originalMessage: string): string => { + try { + const words = originalMessage.split(' '); + const updateWordIndex = words.indexOf('update'); + const firstTableName = words.at(updateWordIndex + 5); + const violatesWordIndex = words.indexOf('violates'); + const secondTableName = words.at(violatesWordIndex + 7); + const message = ` You tried to change a record in a table ${firstTableName}, but this table is referenced by the ${secondTableName} table. Before the operation, you need to update/delete the associated record in table ${secondTableName} or set up in that table an option with operation for the associated entry ("Cascade option"). `; - return message; - } catch (_e) { - return originalMessage; - } - }, - VIOLATES_FOREIGN_CONSTRAINT_MYSQL: (originalMessage: string) => { - const words = originalMessage.split(' '); - const regex = /(?<=\()[^)]+(?=\))/g; - const referencesWordIndex = words.indexOf('references'); - const tableName = words.at(referencesWordIndex + 1); - const relatedColumnName = words.at(referencesWordIndex + 2).match(regex); - const message = ` + return message; + } catch (_e) { + return originalMessage; + } + }, + VIOLATES_FOREIGN_CONSTRAINT_MYSQL: (originalMessage: string) => { + const words = originalMessage.split(' '); + const regex = /(?<=\()[^)]+(?=\))/g; + const referencesWordIndex = words.indexOf('references'); + const tableName = words.at(referencesWordIndex + 1); + const relatedColumnName = words.at(referencesWordIndex + 2).match(regex); + const message = ` You tried to change a record in a table ${tableName}, but another table references on ${relatedColumnName} field in this table. Before the operation, you need to update/delete the associated record in that table or set up in that table an option with operation for the associated entry ("Cascade option"). `; - return message; - }, - VIOLATES_FOREIGN_CONSTRAINT_MSSQL: (originalMessage: string) => { - const words = originalMessage.split(' '); - const fromWordIndex = words.indexOf('from'); - const firstTableName = words.at(fromWordIndex + 1); - const tableWordIndex = words.indexOf('table'); - const secondTableName = words.at(tableWordIndex + 1); - const message = ` + return message; + }, + VIOLATES_FOREIGN_CONSTRAINT_MSSQL: (originalMessage: string) => { + const words = originalMessage.split(' '); + const fromWordIndex = words.indexOf('from'); + const firstTableName = words.at(fromWordIndex + 1); + const tableWordIndex = words.indexOf('table'); + const secondTableName = words.at(tableWordIndex + 1); + const message = ` You tried to change a record in a table ${firstTableName}, but this table is referenced by the ${secondTableName} table. Before the operation, you need to update/delete the associated record in table ${secondTableName} or set up in that table an option with operation for the associated entry ("Cascade option"). `; - return message; - }, - SELECT_COMMAND_DENIED_MYSQL: (originalMessage: string): string => { - const words = originalMessage.split(' '); - const userWordIndex = words.indexOf('user'); - const dbUser = words.at(userWordIndex + 1); - const message = ` + return message; + }, + SELECT_COMMAND_DENIED_MYSQL: (originalMessage: string): string => { + const words = originalMessage.split(' '); + const userWordIndex = words.indexOf('user'); + const dbUser = words.at(userWordIndex + 1); + const message = ` User ${dbUser} don't have permission to perform select command for this table. Please grant select permissions to user in your database. `; - return message; - }, + return message; + }, - Malformed_UTF_data: 'Failed to decrypt connection. Please check that master password is correct.', + Malformed_UTF_data: 'Failed to decrypt connection. Please check that master password is correct.', }; diff --git a/backend/src/guards/company-admin.guard.ts b/backend/src/guards/company-admin.guard.ts index ceeefe664..35702a20c 100644 --- a/backend/src/guards/company-admin.guard.ts +++ b/backend/src/guards/company-admin.guard.ts @@ -1,53 +1,53 @@ -import { Injectable, CanActivate, Inject, ExecutionContext, HttpException, HttpStatus } from '@nestjs/common'; +import { CanActivate, ExecutionContext, HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; +import { Observable } from 'rxjs'; +import { IRequestWithCognitoInfo } from '../authorization/cognito-decoded.interface.js'; import { IGlobalDatabaseContext } from '../common/application/global-database-context.interface.js'; import { BaseType } from '../common/data-injection.tokens.js'; -import { IRequestWithCognitoInfo } from '../authorization/cognito-decoded.interface.js'; -import { Observable } from 'rxjs'; -import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; -import { UserEntity } from '../entities/user/user.entity.js'; import { UserRoleEnum } from '../entities/user/enums/user-role.enum.js'; +import { UserEntity } from '../entities/user/user.entity.js'; import { Messages } from '../exceptions/text/messages.js'; +import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; @Injectable() export class CompanyAdminGuard implements CanActivate { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) {} + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) {} - canActivate(context: ExecutionContext): boolean | Promise | Observable { - return new Promise(async (resolve, reject) => { - const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); - const userId: string = request.decoded.sub; - let companyId: string = request.params?.companyId || request.params?.slug; - if (!companyId || !validateUuidByRegex(companyId)) { - companyId = request.body?.companyId; - } - if (!companyId || !validateUuidByRegex(companyId)) { - const foundCompanyInfo = await this._dbContext.companyInfoRepository.findCompanyInfoByUserId(userId); - companyId = foundCompanyInfo?.id; - } - if (!companyId || !validateUuidByRegex(companyId)) { - resolve(false); - return; - } - let foundUser: UserEntity; - try { - foundUser = await this._dbContext.userRepository.findOneUserByIdAndCompanyId(userId, companyId); - if (foundUser.suspended) { - throw new HttpException( - { - message: Messages.ACCOUNT_SUSPENDED, - }, - HttpStatus.BAD_REQUEST, - ); - } - resolve(foundUser?.role === UserRoleEnum.ADMIN); - return; - } catch (e) { - reject(e); - return; - } - }); - } + canActivate(context: ExecutionContext): boolean | Promise | Observable { + return new Promise(async (resolve, reject) => { + const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); + const userId: string = request.decoded.sub; + let companyId: string = request.params?.companyId || request.params?.slug; + if (!companyId || !validateUuidByRegex(companyId)) { + companyId = request.body?.companyId; + } + if (!companyId || !validateUuidByRegex(companyId)) { + const foundCompanyInfo = await this._dbContext.companyInfoRepository.findCompanyInfoByUserId(userId); + companyId = foundCompanyInfo?.id; + } + if (!companyId || !validateUuidByRegex(companyId)) { + resolve(false); + return; + } + let foundUser: UserEntity; + try { + foundUser = await this._dbContext.userRepository.findOneUserByIdAndCompanyId(userId, companyId); + if (foundUser.suspended) { + throw new HttpException( + { + message: Messages.ACCOUNT_SUSPENDED, + }, + HttpStatus.BAD_REQUEST, + ); + } + resolve(foundUser?.role === UserRoleEnum.ADMIN); + return; + } catch (e) { + reject(e); + return; + } + }); + } } diff --git a/backend/src/guards/company-user.guard.ts b/backend/src/guards/company-user.guard.ts index d8e16bbf4..e29b7df9b 100644 --- a/backend/src/guards/company-user.guard.ts +++ b/backend/src/guards/company-user.guard.ts @@ -1,57 +1,57 @@ -import { Injectable, CanActivate, Inject, ExecutionContext, HttpException, HttpStatus } from '@nestjs/common'; +import { CanActivate, ExecutionContext, HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; +import { Observable } from 'rxjs'; +import { IRequestWithCognitoInfo } from '../authorization/cognito-decoded.interface.js'; import { IGlobalDatabaseContext } from '../common/application/global-database-context.interface.js'; import { BaseType } from '../common/data-injection.tokens.js'; -import { IRequestWithCognitoInfo } from '../authorization/cognito-decoded.interface.js'; -import { Observable } from 'rxjs'; -import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; -import { UserEntity } from '../entities/user/user.entity.js'; import { UserRoleEnum } from '../entities/user/enums/user-role.enum.js'; +import { UserEntity } from '../entities/user/user.entity.js'; import { Messages } from '../exceptions/text/messages.js'; +import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; @Injectable() export class CompanyUserGuard implements CanActivate { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) {} + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) {} - canActivate(context: ExecutionContext): boolean | Promise | Observable { - return new Promise(async (resolve, reject) => { - const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); - const userId: string = request.decoded.sub; - let companyId: string = request.params?.companyId || request.params?.slug; - if (!companyId || !validateUuidByRegex(companyId)) { - companyId = request.body?.companyId; - } - if (!companyId || !validateUuidByRegex(companyId)) { - const foundCompanyInfo = await this._dbContext.companyInfoRepository.findCompanyInfoByUserId(userId); - companyId = foundCompanyInfo?.id; - } - if (!companyId || !validateUuidByRegex(companyId)) { - resolve(false); - return; - } - let foundUser: UserEntity; - try { - foundUser = await this._dbContext.userRepository.findOneUserByIdAndCompanyId(userId, companyId); - if (foundUser.suspended) { - throw new HttpException( - { - message: Messages.ACCOUNT_SUSPENDED, - }, - HttpStatus.BAD_REQUEST, - ); - } - resolve( - foundUser?.role === UserRoleEnum.ADMIN || - foundUser?.role === UserRoleEnum.USER || - foundUser?.role === UserRoleEnum.DB_ADMIN, - ); - return; - } catch (e) { - reject(e); - return; - } - }); - } + canActivate(context: ExecutionContext): boolean | Promise | Observable { + return new Promise(async (resolve, reject) => { + const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); + const userId: string = request.decoded.sub; + let companyId: string = request.params?.companyId || request.params?.slug; + if (!companyId || !validateUuidByRegex(companyId)) { + companyId = request.body?.companyId; + } + if (!companyId || !validateUuidByRegex(companyId)) { + const foundCompanyInfo = await this._dbContext.companyInfoRepository.findCompanyInfoByUserId(userId); + companyId = foundCompanyInfo?.id; + } + if (!companyId || !validateUuidByRegex(companyId)) { + resolve(false); + return; + } + let foundUser: UserEntity; + try { + foundUser = await this._dbContext.userRepository.findOneUserByIdAndCompanyId(userId, companyId); + if (foundUser.suspended) { + throw new HttpException( + { + message: Messages.ACCOUNT_SUSPENDED, + }, + HttpStatus.BAD_REQUEST, + ); + } + resolve( + foundUser?.role === UserRoleEnum.ADMIN || + foundUser?.role === UserRoleEnum.USER || + foundUser?.role === UserRoleEnum.DB_ADMIN, + ); + return; + } catch (e) { + reject(e); + return; + } + }); + } } diff --git a/backend/src/guards/connection-edit.guard.ts b/backend/src/guards/connection-edit.guard.ts index f676fbf1b..5ff244ec5 100644 --- a/backend/src/guards/connection-edit.guard.ts +++ b/backend/src/guards/connection-edit.guard.ts @@ -1,55 +1,55 @@ import { - BadRequestException, - CanActivate, - ExecutionContext, - ForbiddenException, - Inject, - Injectable, + BadRequestException, + CanActivate, + ExecutionContext, + ForbiddenException, + Inject, + Injectable, } from '@nestjs/common'; import { Observable } from 'rxjs'; import { IRequestWithCognitoInfo } from '../authorization/index.js'; -import { Messages } from '../exceptions/text/messages.js'; -import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; -import { BaseType } from '../common/data-injection.tokens.js'; import { IGlobalDatabaseContext } from '../common/application/global-database-context.interface.js'; +import { BaseType } from '../common/data-injection.tokens.js'; +import { Messages } from '../exceptions/text/messages.js'; import { ValidationHelper } from '../helpers/validators/validation-helper.js'; +import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; @Injectable() export class ConnectionEditGuard implements CanActivate { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) {} + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) {} - canActivate(context: ExecutionContext): boolean | Promise | Observable { - return new Promise(async (resolve, reject) => { - const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); - const cognitoUserName = request.decoded.sub; - let connectionId: string = request.query.connectionId; - if (!connectionId || (!validateUuidByRegex(connectionId) && !ValidationHelper.isValidNanoId(connectionId))) { - connectionId = request.params?.slug || request.params?.connectionId; - } - if (!connectionId || (!validateUuidByRegex(connectionId) && !ValidationHelper.isValidNanoId(connectionId))) { - reject(new BadRequestException(Messages.CONNECTION_ID_MISSING)); - return; - } - let userConnectionEdit = false; - try { - userConnectionEdit = await this._dbContext.userAccessRepository.checkUserConnectionEdit( - cognitoUserName, - connectionId, - ); - } catch (e) { - reject(e); - return; - } - if (userConnectionEdit) { - resolve(true); - return; - } else { - reject(new ForbiddenException(Messages.DONT_HAVE_PERMISSIONS)); - return; - } - }); - } + canActivate(context: ExecutionContext): boolean | Promise | Observable { + return new Promise(async (resolve, reject) => { + const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); + const cognitoUserName = request.decoded.sub; + let connectionId: string = request.query.connectionId; + if (!connectionId || (!validateUuidByRegex(connectionId) && !ValidationHelper.isValidNanoId(connectionId))) { + connectionId = request.params?.slug || request.params?.connectionId; + } + if (!connectionId || (!validateUuidByRegex(connectionId) && !ValidationHelper.isValidNanoId(connectionId))) { + reject(new BadRequestException(Messages.CONNECTION_ID_MISSING)); + return; + } + let userConnectionEdit = false; + try { + userConnectionEdit = await this._dbContext.userAccessRepository.checkUserConnectionEdit( + cognitoUserName, + connectionId, + ); + } catch (e) { + reject(e); + return; + } + if (userConnectionEdit) { + resolve(true); + return; + } else { + reject(new ForbiddenException(Messages.DONT_HAVE_PERMISSIONS)); + return; + } + }); + } } diff --git a/backend/src/guards/connection-read.guard.ts b/backend/src/guards/connection-read.guard.ts index 1c1896302..da9957cb6 100644 --- a/backend/src/guards/connection-read.guard.ts +++ b/backend/src/guards/connection-read.guard.ts @@ -1,55 +1,55 @@ import { - BadRequestException, - CanActivate, - ExecutionContext, - ForbiddenException, - Inject, - Injectable, + BadRequestException, + CanActivate, + ExecutionContext, + ForbiddenException, + Inject, + Injectable, } from '@nestjs/common'; import { Observable } from 'rxjs'; import { IRequestWithCognitoInfo } from '../authorization/index.js'; import { IGlobalDatabaseContext } from '../common/application/global-database-context.interface.js'; import { BaseType } from '../common/data-injection.tokens.js'; import { Messages } from '../exceptions/text/messages.js'; -import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; import { ValidationHelper } from '../helpers/validators/validation-helper.js'; +import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; @Injectable() export class ConnectionReadGuard implements CanActivate { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) {} + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) {} - canActivate(context: ExecutionContext): boolean | Promise | Observable { - return new Promise(async (resolve, reject) => { - const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); - const cognitoUserName = request.decoded.sub; - let connectionId: string = request.params?.slug || request.params?.connectionId; - if (!connectionId || (!validateUuidByRegex(connectionId) && !ValidationHelper.isValidNanoId(connectionId))) { - connectionId = request.query.connectionId; - } - if (!connectionId || (!validateUuidByRegex(connectionId) && !ValidationHelper.isValidNanoId(connectionId))) { - reject(new BadRequestException(Messages.CONNECTION_ID_MISSING)); - return; - } - let userConnectionRead = false; - try { - userConnectionRead = await this._dbContext.userAccessRepository.checkUserConnectionRead( - cognitoUserName, - connectionId, - ); - } catch (e) { - reject(e); - return; - } - if (userConnectionRead) { - resolve(true); - return; - } else { - reject(new ForbiddenException(Messages.DONT_HAVE_PERMISSIONS)); - return; - } - }); - } + canActivate(context: ExecutionContext): boolean | Promise | Observable { + return new Promise(async (resolve, reject) => { + const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); + const cognitoUserName = request.decoded.sub; + let connectionId: string = request.params?.slug || request.params?.connectionId; + if (!connectionId || (!validateUuidByRegex(connectionId) && !ValidationHelper.isValidNanoId(connectionId))) { + connectionId = request.query.connectionId; + } + if (!connectionId || (!validateUuidByRegex(connectionId) && !ValidationHelper.isValidNanoId(connectionId))) { + reject(new BadRequestException(Messages.CONNECTION_ID_MISSING)); + return; + } + let userConnectionRead = false; + try { + userConnectionRead = await this._dbContext.userAccessRepository.checkUserConnectionRead( + cognitoUserName, + connectionId, + ); + } catch (e) { + reject(e); + return; + } + if (userConnectionRead) { + resolve(true); + return; + } else { + reject(new ForbiddenException(Messages.DONT_HAVE_PERMISSIONS)); + return; + } + }); + } } diff --git a/backend/src/guards/group-edit.guard.ts b/backend/src/guards/group-edit.guard.ts index 97ad1e94b..4f61801eb 100644 --- a/backend/src/guards/group-edit.guard.ts +++ b/backend/src/guards/group-edit.guard.ts @@ -1,10 +1,10 @@ import { - BadRequestException, - CanActivate, - ExecutionContext, - ForbiddenException, - Inject, - Injectable, + BadRequestException, + CanActivate, + ExecutionContext, + ForbiddenException, + Inject, + Injectable, } from '@nestjs/common'; import { Observable } from 'rxjs'; import { IRequestWithCognitoInfo } from '../authorization/index.js'; @@ -15,38 +15,38 @@ import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; @Injectable() export class GroupEditGuard implements CanActivate { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) {} + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) {} - canActivate(context: ExecutionContext): boolean | Promise | Observable { - return new Promise(async (resolve, reject) => { - const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); - const cognitoUserName = request.decoded.sub; - let groupId: string = request.params?.groupId || request.params?.slug; - if (!groupId || !validateUuidByRegex(groupId)) { - groupId = request.body.groupId; - } - if (!groupId || !validateUuidByRegex(groupId)) { - reject(new BadRequestException(Messages.GROUP_ID_MISSING)); - return; - } - let userGroupEdit = false; - try { - userGroupEdit = await this._dbContext.userAccessRepository.checkUserGroupEdit(cognitoUserName, groupId); - } catch (e) { - reject(e); - return; - } + canActivate(context: ExecutionContext): boolean | Promise | Observable { + return new Promise(async (resolve, reject) => { + const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); + const cognitoUserName = request.decoded.sub; + let groupId: string = request.params?.groupId || request.params?.slug; + if (!groupId || !validateUuidByRegex(groupId)) { + groupId = request.body.groupId; + } + if (!groupId || !validateUuidByRegex(groupId)) { + reject(new BadRequestException(Messages.GROUP_ID_MISSING)); + return; + } + let userGroupEdit = false; + try { + userGroupEdit = await this._dbContext.userAccessRepository.checkUserGroupEdit(cognitoUserName, groupId); + } catch (e) { + reject(e); + return; + } - if (userGroupEdit) { - resolve(true); - return; - } else { - reject(new ForbiddenException(Messages.DONT_HAVE_PERMISSIONS)); - return; - } - }); - } + if (userGroupEdit) { + resolve(true); + return; + } else { + reject(new ForbiddenException(Messages.DONT_HAVE_PERMISSIONS)); + return; + } + }); + } } diff --git a/backend/src/guards/group-read.guard.ts b/backend/src/guards/group-read.guard.ts index a44755c7d..bdc971833 100644 --- a/backend/src/guards/group-read.guard.ts +++ b/backend/src/guards/group-read.guard.ts @@ -1,10 +1,10 @@ import { - BadRequestException, - CanActivate, - ExecutionContext, - ForbiddenException, - Inject, - Injectable, + BadRequestException, + CanActivate, + ExecutionContext, + ForbiddenException, + Inject, + Injectable, } from '@nestjs/common'; import { Observable } from 'rxjs'; import { IRequestWithCognitoInfo } from '../authorization/index.js'; @@ -15,37 +15,37 @@ import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; @Injectable() export class GroupReadGuard implements CanActivate { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) {} + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) {} - canActivate(context: ExecutionContext): boolean | Promise | Observable { - return new Promise(async (resolve, reject) => { - const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); - const cognitoUserName = request.decoded.sub; - let groupId: string = request.params?.groupId || request.params?.slug; - if (!groupId || !validateUuidByRegex(groupId)) { - groupId = request.body.groupId; - } - if (!groupId || !validateUuidByRegex(groupId)) { - reject(new BadRequestException(Messages.GROUP_ID_MISSING)); - return; - } - let userGroupRead = false; - try { - userGroupRead = await this._dbContext.userAccessRepository.checkUserGroupRead(cognitoUserName, groupId); - } catch (e) { - reject(e); - return; - } - if (userGroupRead) { - resolve(true); - return; - } else { - reject(new ForbiddenException(Messages.DONT_HAVE_PERMISSIONS)); - return; - } - }); - } + canActivate(context: ExecutionContext): boolean | Promise | Observable { + return new Promise(async (resolve, reject) => { + const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); + const cognitoUserName = request.decoded.sub; + let groupId: string = request.params?.groupId || request.params?.slug; + if (!groupId || !validateUuidByRegex(groupId)) { + groupId = request.body.groupId; + } + if (!groupId || !validateUuidByRegex(groupId)) { + reject(new BadRequestException(Messages.GROUP_ID_MISSING)); + return; + } + let userGroupRead = false; + try { + userGroupRead = await this._dbContext.userAccessRepository.checkUserGroupRead(cognitoUserName, groupId); + } catch (e) { + reject(e); + return; + } + if (userGroupRead) { + resolve(true); + return; + } else { + reject(new ForbiddenException(Messages.DONT_HAVE_PERMISSIONS)); + return; + } + }); + } } diff --git a/backend/src/guards/paid-feature.guard.ts b/backend/src/guards/paid-feature.guard.ts index 4cf8469d0..8b47755af 100644 --- a/backend/src/guards/paid-feature.guard.ts +++ b/backend/src/guards/paid-feature.guard.ts @@ -1,59 +1,59 @@ import { BadRequestException, CanActivate, ExecutionContext, Inject, Injectable } from '@nestjs/common'; -import { BaseType } from '../common/data-injection.tokens.js'; -import { IGlobalDatabaseContext } from '../common/application/global-database-context.interface.js'; import { Observable } from 'rxjs'; import { IRequestWithCognitoInfo } from '../authorization/cognito-decoded.interface.js'; -import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; -import { SaasCompanyGatewayService } from '../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; -import { isSaaS } from '../helpers/app/is-saas.js'; +import { IGlobalDatabaseContext } from '../common/application/global-database-context.interface.js'; +import { BaseType } from '../common/data-injection.tokens.js'; import { SubscriptionLevelEnum } from '../enums/subscription-level.enum.js'; -import { Messages } from '../exceptions/text/messages.js'; import { NonAvailableInFreePlanException } from '../exceptions/custom-exceptions/non-available-in-free-plan-exception.js'; +import { Messages } from '../exceptions/text/messages.js'; +import { isSaaS } from '../helpers/app/is-saas.js'; +import { SaasCompanyGatewayService } from '../microservices/gateways/saas-gateway.ts/saas-company-gateway.service.js'; +import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; @Injectable() export class PaidFeatureGuard implements CanActivate { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private readonly saasCompanyGatewayService: SaasCompanyGatewayService, - ) {} + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly saasCompanyGatewayService: SaasCompanyGatewayService, + ) {} - canActivate(context: ExecutionContext): boolean | Promise | Observable { - return new Promise(async (resolve, reject) => { - const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); - const userId: string = request.decoded.sub; - let companyId: string = request.params?.companyId || request.params?.slug; - if (!companyId || !validateUuidByRegex(companyId)) { - companyId = request.body?.companyId; - } - if (!companyId || !validateUuidByRegex(companyId)) { - const foundCompanyInfo = await this._dbContext.companyInfoRepository.findCompanyInfoByUserId(userId); - companyId = foundCompanyInfo?.id; - } - if (!companyId || !validateUuidByRegex(companyId)) { - reject(new BadRequestException(Messages.COMPANY_ID_MISSING)); - return; - } - if (!isSaaS()) { - resolve(true); - return; - } - try { - const companyInfo = await this.saasCompanyGatewayService.getCompanyInfo(companyId); - if (!companyInfo) { - reject(new BadRequestException(Messages.COMPANY_NOT_FOUND)); - return; - } - if (companyInfo.subscriptionLevel === SubscriptionLevelEnum.FREE_PLAN) { - reject(new NonAvailableInFreePlanException()); - return; - } - console.log('PaidFeatureGuard: Company has a paid subscription'); - resolve(true); - } catch (e) { - reject(e); - } - return; - }); - } + canActivate(context: ExecutionContext): boolean | Promise | Observable { + return new Promise(async (resolve, reject) => { + const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); + const userId: string = request.decoded.sub; + let companyId: string = request.params?.companyId || request.params?.slug; + if (!companyId || !validateUuidByRegex(companyId)) { + companyId = request.body?.companyId; + } + if (!companyId || !validateUuidByRegex(companyId)) { + const foundCompanyInfo = await this._dbContext.companyInfoRepository.findCompanyInfoByUserId(userId); + companyId = foundCompanyInfo?.id; + } + if (!companyId || !validateUuidByRegex(companyId)) { + reject(new BadRequestException(Messages.COMPANY_ID_MISSING)); + return; + } + if (!isSaaS()) { + resolve(true); + return; + } + try { + const companyInfo = await this.saasCompanyGatewayService.getCompanyInfo(companyId); + if (!companyInfo) { + reject(new BadRequestException(Messages.COMPANY_NOT_FOUND)); + return; + } + if (companyInfo.subscriptionLevel === SubscriptionLevelEnum.FREE_PLAN) { + reject(new NonAvailableInFreePlanException()); + return; + } + console.log('PaidFeatureGuard: Company has a paid subscription'); + resolve(true); + } catch (e) { + reject(e); + } + return; + }); + } } diff --git a/backend/src/guards/table-add.guard.ts b/backend/src/guards/table-add.guard.ts index 57e26e3e9..0ce4a21bb 100644 --- a/backend/src/guards/table-add.guard.ts +++ b/backend/src/guards/table-add.guard.ts @@ -1,10 +1,10 @@ import { - BadRequestException, - CanActivate, - ExecutionContext, - ForbiddenException, - Inject, - Injectable, + BadRequestException, + CanActivate, + ExecutionContext, + ForbiddenException, + Inject, + Injectable, } from '@nestjs/common'; import { Observable } from 'rxjs'; import { IRequestWithCognitoInfo } from '../authorization/index.js'; @@ -12,50 +12,50 @@ import { IGlobalDatabaseContext } from '../common/application/global-database-co import { BaseType } from '../common/data-injection.tokens.js'; import { Messages } from '../exceptions/text/messages.js'; import { getMasterPwd } from '../helpers/index.js'; -import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; import { ValidationHelper } from '../helpers/validators/validation-helper.js'; +import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; @Injectable() export class TableAddGuard implements CanActivate { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) {} + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) {} - canActivate(context: ExecutionContext): boolean | Promise | Observable { - return new Promise(async (resolve, reject) => { - const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); - const cognitoUserName = request.decoded.sub; - const connectionId: string = request.params?.slug || request.params?.connectionId; - const tableName: string = request.query?.tableName; - const masterPwd = getMasterPwd(request); - if (!tableName) { - reject(new BadRequestException(Messages.TABLE_NAME_MISSING)); - return; - } - if (!connectionId || (!validateUuidByRegex(connectionId) && !ValidationHelper.isValidNanoId(connectionId))) { - reject(new BadRequestException(Messages.CONNECTION_ID_MISSING)); - return; - } - let userTableAdd = false; - try { - userTableAdd = await this._dbContext.userAccessRepository.checkTableAdd( - cognitoUserName, - connectionId, - tableName, - masterPwd, - ); - } catch (e) { - reject(e); - return; - } - if (userTableAdd) { - resolve(userTableAdd); - return; - } else { - reject(new ForbiddenException(Messages.DONT_HAVE_PERMISSIONS)); - return; - } - }); - } + canActivate(context: ExecutionContext): boolean | Promise | Observable { + return new Promise(async (resolve, reject) => { + const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); + const cognitoUserName = request.decoded.sub; + const connectionId: string = request.params?.slug || request.params?.connectionId; + const tableName: string = request.query?.tableName; + const masterPwd = getMasterPwd(request); + if (!tableName) { + reject(new BadRequestException(Messages.TABLE_NAME_MISSING)); + return; + } + if (!connectionId || (!validateUuidByRegex(connectionId) && !ValidationHelper.isValidNanoId(connectionId))) { + reject(new BadRequestException(Messages.CONNECTION_ID_MISSING)); + return; + } + let userTableAdd = false; + try { + userTableAdd = await this._dbContext.userAccessRepository.checkTableAdd( + cognitoUserName, + connectionId, + tableName, + masterPwd, + ); + } catch (e) { + reject(e); + return; + } + if (userTableAdd) { + resolve(userTableAdd); + return; + } else { + reject(new ForbiddenException(Messages.DONT_HAVE_PERMISSIONS)); + return; + } + }); + } } diff --git a/backend/src/guards/table-delete.guard.ts b/backend/src/guards/table-delete.guard.ts index 96c432d77..b2b3b14a5 100644 --- a/backend/src/guards/table-delete.guard.ts +++ b/backend/src/guards/table-delete.guard.ts @@ -1,10 +1,10 @@ import { - BadRequestException, - CanActivate, - ExecutionContext, - ForbiddenException, - Inject, - Injectable, + BadRequestException, + CanActivate, + ExecutionContext, + ForbiddenException, + Inject, + Injectable, } from '@nestjs/common'; import { Observable } from 'rxjs'; import { IRequestWithCognitoInfo } from '../authorization/index.js'; @@ -12,49 +12,49 @@ import { IGlobalDatabaseContext } from '../common/application/global-database-co import { BaseType } from '../common/data-injection.tokens.js'; import { Messages } from '../exceptions/text/messages.js'; import { getMasterPwd } from '../helpers/index.js'; -import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; import { ValidationHelper } from '../helpers/validators/validation-helper.js'; +import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; @Injectable() export class TableDeleteGuard implements CanActivate { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) {} + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) {} - canActivate(context: ExecutionContext): boolean | Promise | Observable { - return new Promise(async (resolve, reject) => { - const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); - const cognitoUserName = request.decoded.sub; - const connectionId: string = request.params?.slug || request.params?.connectionId; - const tableName: string = request.query?.tableName; - const masterPwd = getMasterPwd(request); - if (!tableName) { - reject(new BadRequestException(Messages.TABLE_NAME_MISSING)); - return; - } - if (!connectionId || (!validateUuidByRegex(connectionId) && !ValidationHelper.isValidNanoId(connectionId))) { - reject(new BadRequestException(Messages.CONNECTION_ID_MISSING)); - return; - } - let userTableDelete = false; - try { - userTableDelete = await this._dbContext.userAccessRepository.checkTableDelete( - cognitoUserName, - connectionId, - tableName, - masterPwd, - ); - } catch (e) { - reject(e); - return; - } - if (userTableDelete) { - resolve(userTableDelete); - } else { - reject(new ForbiddenException(Messages.DONT_HAVE_PERMISSIONS)); - return; - } - }); - } + canActivate(context: ExecutionContext): boolean | Promise | Observable { + return new Promise(async (resolve, reject) => { + const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); + const cognitoUserName = request.decoded.sub; + const connectionId: string = request.params?.slug || request.params?.connectionId; + const tableName: string = request.query?.tableName; + const masterPwd = getMasterPwd(request); + if (!tableName) { + reject(new BadRequestException(Messages.TABLE_NAME_MISSING)); + return; + } + if (!connectionId || (!validateUuidByRegex(connectionId) && !ValidationHelper.isValidNanoId(connectionId))) { + reject(new BadRequestException(Messages.CONNECTION_ID_MISSING)); + return; + } + let userTableDelete = false; + try { + userTableDelete = await this._dbContext.userAccessRepository.checkTableDelete( + cognitoUserName, + connectionId, + tableName, + masterPwd, + ); + } catch (e) { + reject(e); + return; + } + if (userTableDelete) { + resolve(userTableDelete); + } else { + reject(new ForbiddenException(Messages.DONT_HAVE_PERMISSIONS)); + return; + } + }); + } } diff --git a/backend/src/guards/table-edit.guard.ts b/backend/src/guards/table-edit.guard.ts index 101b6150d..f87f15dab 100644 --- a/backend/src/guards/table-edit.guard.ts +++ b/backend/src/guards/table-edit.guard.ts @@ -1,10 +1,10 @@ import { - BadRequestException, - CanActivate, - ExecutionContext, - ForbiddenException, - Inject, - Injectable, + BadRequestException, + CanActivate, + ExecutionContext, + ForbiddenException, + Inject, + Injectable, } from '@nestjs/common'; import { Observable } from 'rxjs'; import { IRequestWithCognitoInfo } from '../authorization/index.js'; @@ -12,50 +12,50 @@ import { IGlobalDatabaseContext } from '../common/application/global-database-co import { BaseType } from '../common/data-injection.tokens.js'; import { Messages } from '../exceptions/text/messages.js'; import { getMasterPwd } from '../helpers/index.js'; -import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; import { ValidationHelper } from '../helpers/validators/validation-helper.js'; +import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; @Injectable() export class TableEditGuard implements CanActivate { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) {} + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) {} - canActivate(context: ExecutionContext): boolean | Promise | Observable { - return new Promise(async (resolve, reject) => { - const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); - const cognitoUserName = request.decoded.sub; - const connectionId: string = request.params?.slug || request.params?.connectionId; - const tableName: string = request.query?.tableName; - const masterPwd = getMasterPwd(request); - if (!tableName) { - reject(new BadRequestException(Messages.TABLE_NAME_MISSING)); - return; - } - if (!connectionId || (!validateUuidByRegex(connectionId) && !ValidationHelper.isValidNanoId(connectionId))) { - reject(new BadRequestException(Messages.CONNECTION_ID_MISSING)); - return; - } - let userTableEdit = false; - try { - userTableEdit = await this._dbContext.userAccessRepository.checkTableEdit( - cognitoUserName, - connectionId, - tableName, - masterPwd, - ); - } catch (e) { - reject(e); - return; - } - if (userTableEdit) { - resolve(userTableEdit); - return; - } else { - reject(new ForbiddenException(Messages.DONT_HAVE_PERMISSIONS)); - return; - } - }); - } + canActivate(context: ExecutionContext): boolean | Promise | Observable { + return new Promise(async (resolve, reject) => { + const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); + const cognitoUserName = request.decoded.sub; + const connectionId: string = request.params?.slug || request.params?.connectionId; + const tableName: string = request.query?.tableName; + const masterPwd = getMasterPwd(request); + if (!tableName) { + reject(new BadRequestException(Messages.TABLE_NAME_MISSING)); + return; + } + if (!connectionId || (!validateUuidByRegex(connectionId) && !ValidationHelper.isValidNanoId(connectionId))) { + reject(new BadRequestException(Messages.CONNECTION_ID_MISSING)); + return; + } + let userTableEdit = false; + try { + userTableEdit = await this._dbContext.userAccessRepository.checkTableEdit( + cognitoUserName, + connectionId, + tableName, + masterPwd, + ); + } catch (e) { + reject(e); + return; + } + if (userTableEdit) { + resolve(userTableEdit); + return; + } else { + reject(new ForbiddenException(Messages.DONT_HAVE_PERMISSIONS)); + return; + } + }); + } } diff --git a/backend/src/guards/table-read.guard.ts b/backend/src/guards/table-read.guard.ts index 2941c6e74..8a7257bff 100644 --- a/backend/src/guards/table-read.guard.ts +++ b/backend/src/guards/table-read.guard.ts @@ -1,10 +1,10 @@ import { - BadRequestException, - CanActivate, - ExecutionContext, - ForbiddenException, - Inject, - Injectable, + BadRequestException, + CanActivate, + ExecutionContext, + ForbiddenException, + Inject, + Injectable, } from '@nestjs/common'; import { Observable } from 'rxjs'; import { IRequestWithCognitoInfo } from '../authorization/index.js'; @@ -12,50 +12,50 @@ import { IGlobalDatabaseContext } from '../common/application/global-database-co import { BaseType } from '../common/data-injection.tokens.js'; import { Messages } from '../exceptions/text/messages.js'; import { getMasterPwd } from '../helpers/index.js'; -import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; import { ValidationHelper } from '../helpers/validators/validation-helper.js'; +import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; @Injectable() export class TableReadGuard implements CanActivate { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) {} + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) {} - canActivate(context: ExecutionContext): boolean | Promise | Observable { - return new Promise(async (resolve, reject) => { - const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); - const cognitoUserName = request.decoded.sub; - const connectionId: string = request.params?.slug || request.params?.connectionId; - const tableName: string = request.query?.tableName; - const masterPwd = getMasterPwd(request); - if (!tableName) { - reject(new BadRequestException(Messages.TABLE_NAME_MISSING)); - return; - } - if (!connectionId || (!validateUuidByRegex(connectionId) && !ValidationHelper.isValidNanoId(connectionId))) { - reject(new BadRequestException(Messages.CONNECTION_ID_MISSING)); - return; - } - let userTableRead = false; - try { - userTableRead = await this._dbContext.userAccessRepository.improvedCheckTableRead( - cognitoUserName, - connectionId, - tableName, - masterPwd, - ); - } catch (e) { - reject(e); - return; - } - if (userTableRead) { - resolve(userTableRead); - return; - } else { - reject(new ForbiddenException(Messages.DONT_HAVE_PERMISSIONS)); - return; - } - }); - } + canActivate(context: ExecutionContext): boolean | Promise | Observable { + return new Promise(async (resolve, reject) => { + const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); + const cognitoUserName = request.decoded.sub; + const connectionId: string = request.params?.slug || request.params?.connectionId; + const tableName: string = request.query?.tableName; + const masterPwd = getMasterPwd(request); + if (!tableName) { + reject(new BadRequestException(Messages.TABLE_NAME_MISSING)); + return; + } + if (!connectionId || (!validateUuidByRegex(connectionId) && !ValidationHelper.isValidNanoId(connectionId))) { + reject(new BadRequestException(Messages.CONNECTION_ID_MISSING)); + return; + } + let userTableRead = false; + try { + userTableRead = await this._dbContext.userAccessRepository.improvedCheckTableRead( + cognitoUserName, + connectionId, + tableName, + masterPwd, + ); + } catch (e) { + reject(e); + return; + } + if (userTableRead) { + resolve(userTableRead); + return; + } else { + reject(new ForbiddenException(Messages.DONT_HAVE_PERMISSIONS)); + return; + } + }); + } } diff --git a/backend/src/guards/tables-receive.guard.ts b/backend/src/guards/tables-receive.guard.ts index 21eeface3..60446dc00 100644 --- a/backend/src/guards/tables-receive.guard.ts +++ b/backend/src/guards/tables-receive.guard.ts @@ -1,51 +1,45 @@ -import { - BadRequestException, - CanActivate, - ExecutionContext, - Inject, - Injectable, -} from '@nestjs/common'; +import { BadRequestException, CanActivate, ExecutionContext, Inject, Injectable } from '@nestjs/common'; import { Observable } from 'rxjs'; +import { IRequestWithCognitoInfo } from '../authorization/cognito-decoded.interface.js'; import { IGlobalDatabaseContext } from '../common/application/global-database-context.interface.js'; import { BaseType } from '../common/data-injection.tokens.js'; -import { IRequestWithCognitoInfo } from '../authorization/cognito-decoded.interface.js'; import { Messages } from '../exceptions/text/messages.js'; import { ValidationHelper } from '../helpers/validators/validation-helper.js'; import { validateUuidByRegex } from './utils/validate-uuid-by-regex.js'; @Injectable() export class TablesReceiveGuard implements CanActivate { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) {} + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) {} - canActivate(context: ExecutionContext): boolean | Promise | Observable { - return new Promise(async (resolve, reject) => { - const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); - const cognitoUserName = request.decoded.sub; - const connectionId: string = request.params?.slug || request.params?.connectionId; - if (!connectionId || (!validateUuidByRegex(connectionId) && !ValidationHelper.isValidNanoId(connectionId))) { - reject(new BadRequestException(Messages.CONNECTION_ID_MISSING)); - return; - } - let canUserReadTables = false; - try { - canUserReadTables = await this._dbContext.connectionRepository.isUserFromConnection( - cognitoUserName, - connectionId, - ); - } catch (error) { - reject(error); - return; - } + canActivate(context: ExecutionContext): boolean | Promise | Observable { + return new Promise(async (resolve, reject) => { + const request: IRequestWithCognitoInfo = context.switchToHttp().getRequest(); + const cognitoUserName = request.decoded.sub; + const connectionId: string = request.params?.slug || request.params?.connectionId; + if (!connectionId || (!validateUuidByRegex(connectionId) && !ValidationHelper.isValidNanoId(connectionId))) { + reject(new BadRequestException(Messages.CONNECTION_ID_MISSING)); + return; + } + let canUserReadTables = false; + try { + canUserReadTables = await this._dbContext.connectionRepository.isUserFromConnection( + cognitoUserName, + connectionId, + ); + } catch (error) { + reject(error); + return; + } - if (canUserReadTables) { - resolve(canUserReadTables); - return; - } else { - reject(new BadRequestException(Messages.CONNECTION_NOT_FOUND)); - } - }); - } + if (canUserReadTables) { + resolve(canUserReadTables); + return; + } else { + reject(new BadRequestException(Messages.CONNECTION_NOT_FOUND)); + } + }); + } } diff --git a/backend/src/guards/utils/validate-uuid-by-regex.ts b/backend/src/guards/utils/validate-uuid-by-regex.ts index 3c6983b73..c94a9cc40 100644 --- a/backend/src/guards/utils/validate-uuid-by-regex.ts +++ b/backend/src/guards/utils/validate-uuid-by-regex.ts @@ -1,5 +1,5 @@ import validator from 'validator'; export const validateUuidByRegex = (uuid: string): boolean => { - return validator.isUUID(uuid); + return validator.isUUID(uuid); }; diff --git a/backend/src/helpers/app/get-requeired-env-variable.ts b/backend/src/helpers/app/get-requeired-env-variable.ts index a01ac6f05..0c62a5b77 100644 --- a/backend/src/helpers/app/get-requeired-env-variable.ts +++ b/backend/src/helpers/app/get-requeired-env-variable.ts @@ -1,13 +1,13 @@ export function getRequiredEnvVariable(variableName: string): string { - // eslint-disable-next-line security/detect-object-injection - const variableValue = process.env[variableName]; - if (!variableValue) { - throw new Error(`Environment variable ${variableName} is not set`); - } - return variableValue; + // eslint-disable-next-line security/detect-object-injection + const variableValue = process.env[variableName]; + if (!variableValue) { + throw new Error(`Environment variable ${variableName} is not set`); + } + return variableValue; } export function getOptionalEnvVariable(variableName: string): string | undefined { - // eslint-disable-next-line security/detect-object-injection - return process.env[variableName]; -} \ No newline at end of file + // eslint-disable-next-line security/detect-object-injection + return process.env[variableName]; +} diff --git a/backend/src/helpers/app/is-saas.ts b/backend/src/helpers/app/is-saas.ts index 690657e9b..b11eda795 100644 --- a/backend/src/helpers/app/is-saas.ts +++ b/backend/src/helpers/app/is-saas.ts @@ -1,6 +1,6 @@ import { getProcessVariable } from '../get-process-variable.js'; export function isSaaS(): boolean { - const isSaaS: unknown = getProcessVariable('IS_SAAS'); - return !!isSaaS; + const isSaaS: unknown = getProcessVariable('IS_SAAS'); + return !!isSaaS; } diff --git a/backend/src/helpers/app/is-test.ts b/backend/src/helpers/app/is-test.ts index 0905816f6..cb770d07d 100644 --- a/backend/src/helpers/app/is-test.ts +++ b/backend/src/helpers/app/is-test.ts @@ -1,3 +1,3 @@ export function isTest(): boolean { - return process.env.NODE_ENV === 'test'; -} \ No newline at end of file + return process.env.NODE_ENV === 'test'; +} diff --git a/backend/src/helpers/binary-to-hex.ts b/backend/src/helpers/binary-to-hex.ts index 61c449dcd..1b9024ee7 100644 --- a/backend/src/helpers/binary-to-hex.ts +++ b/backend/src/helpers/binary-to-hex.ts @@ -1,25 +1,25 @@ import { Constants } from './constants/constants.js'; export function binaryToHex( - binaryData: string | Uint8Array | { [key: string]: number } | { type: string; data: number[] }, + binaryData: string | Uint8Array | { [key: string]: number } | { type: string; data: number[] }, ): string { - let buffer: Buffer; - if (binaryData instanceof Uint8Array) { - buffer = Buffer.from(binaryData); - } else if (typeof binaryData === 'object') { - const data = - binaryData.type === 'Buffer' && Array.isArray(binaryData.data) ? binaryData.data : Object.values(binaryData); - buffer = Buffer.from(data); - } else { - buffer = Buffer.from(binaryData, 'binary'); - } - return buffer.toString('hex'); + let buffer: Buffer; + if (binaryData instanceof Uint8Array) { + buffer = Buffer.from(binaryData); + } else if (typeof binaryData === 'object') { + const data = + binaryData.type === 'Buffer' && Array.isArray(binaryData.data) ? binaryData.data : Object.values(binaryData); + buffer = Buffer.from(data); + } else { + buffer = Buffer.from(binaryData, 'binary'); + } + return buffer.toString('hex'); } export function hexToBinary(hexSource: string): Buffer { - return Buffer.from(hexSource, 'hex'); + return Buffer.from(hexSource, 'hex'); } export function isBinary(type: string): boolean { - return Constants.BINARY_DATATYPES.includes(type.toLowerCase()); + return Constants.BINARY_DATATYPES.includes(type.toLowerCase()); } diff --git a/backend/src/helpers/cache/cacher.ts b/backend/src/helpers/cache/cacher.ts index b0a32c2c9..127393afb 100644 --- a/backend/src/helpers/cache/cacher.ts +++ b/backend/src/helpers/cache/cacher.ts @@ -6,67 +6,67 @@ const invitationCache = new LRUCache(Constants.DEFAULT_INVITATION_CACHE_OPTIONS) const tableReadPermissionCache = new LRUCache(Constants.DEFAULT_TABLE_PERMISSIONS_CACHE_OPTIONS); export class Cacher { - public static setUserTableReadPermissionCache( - userId: string, - connectionId: string, - tableName: string, - permission: boolean, - ): void { - const cacheKey = `${userId}-${connectionId}-${tableName}`; - tableReadPermissionCache.set(cacheKey, permission); - } + public static setUserTableReadPermissionCache( + userId: string, + connectionId: string, + tableName: string, + permission: boolean, + ): void { + const cacheKey = `${userId}-${connectionId}-${tableName}`; + tableReadPermissionCache.set(cacheKey, permission); + } - public static getUserTableReadPermissionCache( - userId: string, - connectionId: string, - tableName: string, - ): boolean | null { - const cacheKey = `${userId}-${connectionId}-${tableName}`; - const permission = tableReadPermissionCache.get(cacheKey) as boolean; - if (permission === null || permission === undefined) { - return null; - } - return permission; - } + public static getUserTableReadPermissionCache( + userId: string, + connectionId: string, + tableName: string, + ): boolean | null { + const cacheKey = `${userId}-${connectionId}-${tableName}`; + const permission = tableReadPermissionCache.get(cacheKey) as boolean; + if (permission === null || permission === undefined) { + return null; + } + return permission; + } - public static clearUserTableReadPermissionCache(userId: string, connectionId: string, tableName: string): void { - const cacheKey = `${userId}-${connectionId}-${tableName}`; - tableReadPermissionCache.delete(cacheKey); - } + public static clearUserTableReadPermissionCache(userId: string, connectionId: string, tableName: string): void { + const cacheKey = `${userId}-${connectionId}-${tableName}`; + tableReadPermissionCache.delete(cacheKey); + } - public static increaseGroupInvitationsCacheCount(groupId: string): void { - let groupCount = Cacher.getGroupInvitationCachedCount(groupId); - invitationCache.set(groupId, ++groupCount); - return; - } + public static increaseGroupInvitationsCacheCount(groupId: string): void { + let groupCount = Cacher.getGroupInvitationCachedCount(groupId); + invitationCache.set(groupId, ++groupCount); + return; + } - public static increaseUserInvitationsCacheCount(userId: string): void { - let userCount = Cacher.getUserInvitationCachedCount(userId); - invitationCache.set(userId, ++userCount); - return; - } + public static increaseUserInvitationsCacheCount(userId: string): void { + let userCount = Cacher.getUserInvitationCachedCount(userId); + invitationCache.set(userId, ++userCount); + return; + } - public static getUserInvitationCachedCount(userId: string): number { - const cachedCount = invitationCache.get(userId) as number; - return cachedCount ? cachedCount : 0; - } + public static getUserInvitationCachedCount(userId: string): number { + const cachedCount = invitationCache.get(userId) as number; + return cachedCount ? cachedCount : 0; + } - public static getGroupInvitationCachedCount(groupId: string): number { - const cachedCount = invitationCache.get(groupId) as number; - return cachedCount ? cachedCount : 0; - } + public static getGroupInvitationCachedCount(groupId: string): number { + const cachedCount = invitationCache.get(groupId) as number; + return cachedCount ? cachedCount : 0; + } - public static canInvite(userId: string, groupId: string): boolean { - if (!isSaaS()) { - return true; - } - const userInvitations = Cacher.getUserInvitationCachedCount(userId); - const groupInvitations = Cacher.getGroupInvitationCachedCount(groupId); - return userInvitations <= 10 && groupInvitations <= 10; - } + public static canInvite(userId: string, groupId: string): boolean { + if (!isSaaS()) { + return true; + } + const userInvitations = Cacher.getUserInvitationCachedCount(userId); + const groupInvitations = Cacher.getGroupInvitationCachedCount(groupId); + return userInvitations <= 10 && groupInvitations <= 10; + } - public static async clearAllCache(): Promise { - await invitationCache.clear(); - await tableReadPermissionCache.clear(); - } + public static async clearAllCache(): Promise { + await invitationCache.clear(); + await tableReadPermissionCache.clear(); + } } diff --git a/backend/src/helpers/check-field-autoincrement.ts b/backend/src/helpers/check-field-autoincrement.ts index 8585f9dbf..f67a1c0a6 100644 --- a/backend/src/helpers/check-field-autoincrement.ts +++ b/backend/src/helpers/check-field-autoincrement.ts @@ -1,14 +1,14 @@ export function checkFieldAutoincrement(defaultValue: string, extra: string = null): boolean { - let result = false; - if ( - (defaultValue?.toLowerCase().includes('nextval')) || - (defaultValue?.toLowerCase().includes('generate')) || - (defaultValue?.toLowerCase().includes('autoincrement')) || - (defaultValue?.toLowerCase().includes('auto_increment')) || - (extra?.toLowerCase().includes('auto_increment')) || - (extra?.toLowerCase().includes('autoincrement')) - ) { - result = true; - } - return result; + let result = false; + if ( + defaultValue?.toLowerCase().includes('nextval') || + defaultValue?.toLowerCase().includes('generate') || + defaultValue?.toLowerCase().includes('autoincrement') || + defaultValue?.toLowerCase().includes('auto_increment') || + extra?.toLowerCase().includes('auto_increment') || + extra?.toLowerCase().includes('autoincrement') + ) { + result = true; + } + return result; } diff --git a/backend/src/helpers/compare-array-elements.ts b/backend/src/helpers/compare-array-elements.ts index 2a1d2acaf..22ce708b6 100644 --- a/backend/src/helpers/compare-array-elements.ts +++ b/backend/src/helpers/compare-array-elements.ts @@ -1,12 +1,12 @@ export function compareArrayElements(arr1: Array, arr2: Array): boolean { - if (arr1.length !== arr2.length) { - return false; - } - for (let i = 0; i < arr1.length; i++) { - const include = arr2.includes(arr1.at(i)); - if (!include) { - return false; - } - } - return true; + if (arr1.length !== arr2.length) { + return false; + } + for (let i = 0; i < arr1.length; i++) { + const include = arr2.includes(arr1.at(i)); + if (!include) { + return false; + } + } + return true; } diff --git a/backend/src/helpers/constants/constants.ts b/backend/src/helpers/constants/constants.ts index 64224f093..b66ac59bb 100644 --- a/backend/src/helpers/constants/constants.ts +++ b/backend/src/helpers/constants/constants.ts @@ -1,313 +1,313 @@ -import { CreateConnectionDto } from '../../entities/connection/application/dto/create-connection.dto.js'; +import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; import { Knex } from 'knex'; -import { getProcessVariable } from '../get-process-variable.js'; +import { CreateConnectionDto } from '../../entities/connection/application/dto/create-connection.dto.js'; import { isSaaS } from '../app/is-saas.js'; +import { isTest } from '../app/is-test.js'; +import { getProcessVariable } from '../get-process-variable.js'; import { - parseTestMySQLConnectionString, - parseTestPostgresConnectionString, - parseTestMSSQLConnectionString, - parseTestOracleDBConnectionString, - parseTestMongoDBConnectionString, - parseTestDynamoDBConnectionString, + parseTestDynamoDBConnectionString, + parseTestMongoDBConnectionString, + parseTestMSSQLConnectionString, + parseTestMySQLConnectionString, + parseTestOracleDBConnectionString, + parseTestPostgresConnectionString, } from '../parsers/string-connection-to-database-parsers.js'; -import { isTest } from '../app/is-test.js'; -import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; export type TestConnectionsFromJSON = { - //string value represents the connection string, to connect to the database - 'test-mysql': string; - 'test-postgres': string; - 'test-mssql': string; - 'test-oracle': string; - 'test-mongo': string; - 'test-ibmdb2': string; + //string value represents the connection string, to connect to the database + 'test-mysql': string; + 'test-postgres': string; + 'test-mssql': string; + 'test-oracle': string; + 'test-mongo': string; + 'test-ibmdb2': string; }; export const Constants = { - ROCKETADMIN_AUTHENTICATED_COOKIE: 'rocketadmin_authenticated', - JWT_COOKIE_KEY_NAME: 'rocketadmin_cookie', - FORBIDDEN_HOSTS: ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', '127.0.0.0/8', 'fd00::/8'], - BINARY_DATATYPES: [ - 'binary', - 'bytea', - 'varbinary', - 'varbinary(max)', - 'tinyblob', - 'blob', - 'mediumblob', - 'longblob', - 'raw', - ], - DEFAULT_LOG_ROWS_LIMIT: 500, - MIDNIGHT_CRON_KEY: 1, - MORNING_CRON_KEY: 2, - CONNECTION_KEYS_NONE_PERMISSION: ['id', 'title', 'database', 'type', 'connection_properties', 'isTestConnection'], - FREE_PLAN_USERS_COUNT: 3, - NON_FREE_PLAN_CONNECTION_TYPES: [ConnectionTypesEnum.ibmdb2, ConnectionTypesEnum.mssql, ConnectionTypesEnum.oracledb], - MAX_FILE_SIZE_IN_BYTES: 10485760, - MAX_COMPANY_LOGO_SIZE: 5242880, - MAX_COMPANY_FAVICON_SIZE: 5242880, - PAID_CONNECTIONS_TYPES: [ConnectionTypesEnum.oracledb, ConnectionTypesEnum.ibmdb2, ConnectionTypesEnum.mssql], - - VERIFICATION_STRING_WHITELIST: () => { - const numbers = [...Array(10).keys()].map((num) => num.toString()); - const alpha = Array.from(Array(26)).map((_e, i) => i + 65); - const letters = alpha.map((x) => String.fromCharCode(x).toLowerCase()); - return [...numbers, ...letters]; - }, - - PASSWORD_SALT_LENGTH: 64, - BYTE_TO_STRING_ENCODING: 'hex' as BufferEncoding, - PASSWORD_HASH_ITERATIONS: 10000, - PASSWORD_LENGTH: 256, - DIGEST: 'sha512', - - CURRENT_TIME_FORMATTED: (): string => { - const now = new Date(); - const padString = (n: number) => n.toString().padStart(2, '0'); - return `${padString(now.getHours())}:${padString(now.getMinutes())}:${padString(now.getSeconds())}`; - }, - - ONE_WEEK_AGO: (): Date => { - const today = new Date(); - const oneWeekAgo = today.getDate() - 7; - today.setDate(oneWeekAgo); - return today; - }, - - ONE_MONTH_AND_A_WEEK_AGO: (): Date => { - const today = new Date(); - const oneMonthAgo = today.getMonth() - 1; - const oneWeekAgo = today.getDate() - 7; - today.setMonth(oneMonthAgo); - today.setDate(oneWeekAgo); - return today; - }, - - TWO_WEEKS_AGO: (): Date => { - const currentDate = Date.now(); - const twoWeeksInMs = 1209600000; - const dateTwoWeeksAgoInMs = currentDate - twoWeeksInMs; - return new Date(dateTwoWeeksAgoInMs); - }, - - ONE_DAY_AGO: (): Date => { - return new Date(Date.now() - 24 * 60 * 60 * 1000); - }, - - CRON_SHEDULE: '30 5 13 * * *', - COUNT_QUERY_TIMEOUT_MS: 2000, - EMAIL_VALIDATION_TIMEOUT: 1000, - - DEFAULT_PAGINATION: { page: 1, perPage: 20 }, - - LARGE_DATASET_ROW_LIMIT: 100000, - - DEFAULT_SLACK_CHANNEL: '#errors', - EXCEPTIONS_CHANNELS: '#errors', - KEEP_ALIVE_INTERVAL: 30000, - KEEP_ALIVE_COUNT_MAX: 120, - - DEFAULT_CONNECTION_CACHE_OPTIONS: { - max: 150, - ttl: 1000 * 60 * 60, - updateAgeOnGet: false, - updateAgeOnHas: false, - dispose: async (knex: Knex) => { - await knex.destroy(); - }, - }, - - DEFAULT_INVITATION_CACHE_OPTIONS: { - max: 200, - ttl: 1000 * 60 * 60, - }, - - DEFAULT_TABLE_PERMISSIONS_CACHE_OPTIONS: { - max: 1000, - ttl: 1000 * 10, - }, - - DEFAULT_FORWARD_IN_HOST: '127.0.0.1', - AUTOCOMPLETE_ROW_LIMIT: 20, - - FOREIGN_KEY_FIELDS: ['referenced_column_name', 'referenced_table_name', 'constraint_name', 'column_name'], - - TEST_CONNECTION_TO_POSTGRES: { - title: 'Postgres', - masterEncryption: false, - type: ConnectionTypesEnum.postgres, - username: getProcessVariable('POSTGRES_CONNECTION_USERNAME') || null, - password: getProcessVariable('POSTGRES_CONNECTION_PASSWORD') || null, - host: getProcessVariable('POSTGRES_CONNECTION_HOST') || null, - port: parseInt(getProcessVariable('POSTGRES_CONNECTION_PORT'), 10) || null, - database: getProcessVariable('POSTGRES_CONNECTION_DATABASE') || null, - isTestConnection: true, - }, - - TEST_CONNECTION_TO_MSSQL: { - title: 'MSSQL', - masterEncryption: false, - type: ConnectionTypesEnum.mssql, - host: getProcessVariable('MSSQL_CONNECTION_HOST') || null, - port: parseInt(getProcessVariable('MSSQL_CONNECTION_PORT'), 10) || null, - password: getProcessVariable('MSSQL_CONNECTION_PASSWORD') || null, - username: getProcessVariable('MSSQL_CONNECTION_USERNAME') || null, - database: getProcessVariable('MSSQL_CONNECTION_DATABASE') || null, - ssh: false, - ssl: false, - isTestConnection: true, - }, - - TEST_CONNECTION_TO_ORACLE: { - title: 'Oracle', - type: ConnectionTypesEnum.oracledb, - host: getProcessVariable('ORACLE_CONNECTION_HOST') || null, - port: parseInt(getProcessVariable('ORACLE_CONNECTION_PORT'), 10) || null, - username: getProcessVariable('ORACLE_CONNECTION_USERNAME') || null, - password: getProcessVariable('ORACLE_CONNECTION_PASSWORD') || null, - database: getProcessVariable('ORACLE_CONNECTION_DATABASE') || null, - sid: getProcessVariable('ORACLE_CONNECTION_SID') || null, - isTestConnection: true, - }, - - TEST_SSH_CONNECTION_TO_MYSQL: { - title: 'MySQL', - type: ConnectionTypesEnum.mysql, - host: getProcessVariable('MYSQL_CONNECTION_HOST') || null, - port: parseInt(getProcessVariable('MYSQL_CONNECTION_PORT'), 10) || null, - username: getProcessVariable('MYSQL_CONNECTION_USERNAME') || null, - password: getProcessVariable('MYSQL_CONNECTION_PASSWORD') || null, - database: getProcessVariable('MYSQL_CONNECTION_DATABASE') || null, - ssh: true, - isTestConnection: true, - sshHost: getProcessVariable('MYSQL_CONNECTION_SSH_HOST') || null, - sshPort: getProcessVariable('MYSQL_CONNECTION_SSH_PORT') || null, - sshUsername: getProcessVariable('MYSQL_CONNECTION_SSH_USERNAME') || null, - privateSSHKey: getProcessVariable('MYSQL_CONNECTION_SSH_KEY') || null, - }, - - TEST_CONNECTION_TO_MONGO: { - title: 'MongoDB', - type: ConnectionTypesEnum.mongodb, - host: getProcessVariable('MONGO_CONNECTION_HOST') || null, - port: parseInt(getProcessVariable('MONGO_CONNECTION_PORT'), 10) || null, - username: getProcessVariable('MONGO_CONNECTION_USERNAME') || null, - password: getProcessVariable('MONGO_CONNECTION_PASSWORD') || null, - database: getProcessVariable('MONGO_CONNECTION_DATABASE') || null, - authSource: getProcessVariable('MONGO_CONNECTION_AUTH_SOURCE') || null, - isTestConnection: true, - }, - - TEST_CONNECTION_TO_IBMBD2: { - title: 'IBM DB2', - type: ConnectionTypesEnum.ibmdb2, - host: getProcessVariable('IBM_DB2_CONNECTION_HOST') || null, - port: parseInt(getProcessVariable('IBM_DB2_CONNECTION_PORT'), 10) || null, - username: getProcessVariable('IBM_DB2_CONNECTION_USERNAME') || null, - password: getProcessVariable('IBM_DB2_CONNECTION_PASSWORD') || null, - database: getProcessVariable('IBM_DB2_CONNECTION_DATABASE') || null, - schema: getProcessVariable('IBM_DB2_CONNECTION_SCHEMA') || null, - isTestConnection: true, - }, - - REMOVED_PASSWORD_VALUE: '***', - REMOVED_SENSITIVE_FIELD_IF_CHANGED: '* * * sensitive data, no logs stored * * *', - REMOVED_SENSITIVE_FIELD_IF_NOT_CHANGED: '', - - getTestConnectionsArr: (): Array => { - const isSaaS = process.env.IS_SAAS; - if (!isSaaS || isSaaS !== 'true') { - return []; - } - const testConnections: Array = Constants.getTestConnectionsFromDSN() || []; - if (!testConnections.length) { - testConnections.push( - Constants.TEST_CONNECTION_TO_ORACLE as CreateConnectionDto, - Constants.TEST_CONNECTION_TO_POSTGRES as CreateConnectionDto, - Constants.TEST_SSH_CONNECTION_TO_MYSQL as unknown as CreateConnectionDto, - Constants.TEST_CONNECTION_TO_MSSQL as CreateConnectionDto, - Constants.TEST_CONNECTION_TO_MONGO as CreateConnectionDto, - Constants.TEST_CONNECTION_TO_IBMBD2 as CreateConnectionDto, - ); - } - - return testConnections.filter((dto) => { - const values = Object.values(dto); - const nullElementIndex = values.indexOf(null); - return nullElementIndex < 0; - }); - }, - - getTestConnectionsFromDSN: (): Array => { - if (!isSaaS()) { - return []; - } - const testConnectionsJSON = getProcessVariable('TEST_CONNECTIONS'); - if (!testConnectionsJSON) { - return null; - } - try { - const testConnectionsDSNFromJSON: TestConnectionsFromJSON = JSON.parse(testConnectionsJSON); - const testConnectionsArr: Array = []; - for (const [connection_type, connection_string] of Object.entries(testConnectionsDSNFromJSON)) { - let connection: CreateConnectionDto | null = null; - const type = connection_type.toLowerCase(); - switch (true) { - case type.toLowerCase().includes('mysql'): - connection = parseTestMySQLConnectionString(connection_string) as CreateConnectionDto; - break; - case type.toLowerCase().includes('postgres'): - connection = parseTestPostgresConnectionString(connection_string) as CreateConnectionDto; - break; - case type.toLowerCase().includes('mssql'): - connection = parseTestMSSQLConnectionString(connection_string) as CreateConnectionDto; - break; - case type.toLowerCase().includes('oracle'): - connection = parseTestOracleDBConnectionString(connection_string) as CreateConnectionDto; - break; - case type.toLowerCase().includes('mongo'): - connection = parseTestMongoDBConnectionString(connection_string) as CreateConnectionDto; - break; - // case type.toLowerCase().includes('ibmdb2'): - // connection = parseTestIbmDB2ConnectionString(connection_string) as CreateConnectionDto; - // break; - case type.toLowerCase().includes('dynamodb'): - connection = parseTestDynamoDBConnectionString(connection_string) as CreateConnectionDto; - break; - default: - break; - } - if (connection) { - testConnectionsArr.push(connection); - } - } - return testConnectionsArr; - } catch (e) { - console.error('Error parsing test connections from DSN: ' + e); - return null; - } - }, - - getTestConnectionsHostNamesArr: function (): Array { - return this.getTestConnectionsArr().map((connection) => connection.host); - }, - - APP_DOMAIN_ADDRESS: process.env.APP_DOMAIN_ADDRESS || `http://127.0.0.1:3000`, - ALLOWED_REQUEST_DOMAIN: (): string => { - if (isTest()) { - return Constants.APP_DOMAIN_ADDRESS; - } - return `app.rocketadmin.com`; - }, - - APP_REQUEST_DOMAINS(): Array { - const allowedDomains = ['app.rocketadmin.com', 'saas.rocketadmin.com', Constants.APP_DOMAIN_ADDRESS]; - if (isTest()) { - allowedDomains.push('127.0.0.1', Constants.APP_DOMAIN_ADDRESS); - } - return allowedDomains; - }, - - AUTOADMIN_SUPPORT_MAIL: 'support@autoadmin.org', + ROCKETADMIN_AUTHENTICATED_COOKIE: 'rocketadmin_authenticated', + JWT_COOKIE_KEY_NAME: 'rocketadmin_cookie', + FORBIDDEN_HOSTS: ['10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16', '127.0.0.0/8', 'fd00::/8'], + BINARY_DATATYPES: [ + 'binary', + 'bytea', + 'varbinary', + 'varbinary(max)', + 'tinyblob', + 'blob', + 'mediumblob', + 'longblob', + 'raw', + ], + DEFAULT_LOG_ROWS_LIMIT: 500, + MIDNIGHT_CRON_KEY: 1, + MORNING_CRON_KEY: 2, + CONNECTION_KEYS_NONE_PERMISSION: ['id', 'title', 'database', 'type', 'connection_properties', 'isTestConnection'], + FREE_PLAN_USERS_COUNT: 3, + NON_FREE_PLAN_CONNECTION_TYPES: [ConnectionTypesEnum.ibmdb2, ConnectionTypesEnum.mssql, ConnectionTypesEnum.oracledb], + MAX_FILE_SIZE_IN_BYTES: 10485760, + MAX_COMPANY_LOGO_SIZE: 5242880, + MAX_COMPANY_FAVICON_SIZE: 5242880, + PAID_CONNECTIONS_TYPES: [ConnectionTypesEnum.oracledb, ConnectionTypesEnum.ibmdb2, ConnectionTypesEnum.mssql], + + VERIFICATION_STRING_WHITELIST: () => { + const numbers = [...Array(10).keys()].map((num) => num.toString()); + const alpha = Array.from(Array(26)).map((_e, i) => i + 65); + const letters = alpha.map((x) => String.fromCharCode(x).toLowerCase()); + return [...numbers, ...letters]; + }, + + PASSWORD_SALT_LENGTH: 64, + BYTE_TO_STRING_ENCODING: 'hex' as BufferEncoding, + PASSWORD_HASH_ITERATIONS: 10000, + PASSWORD_LENGTH: 256, + DIGEST: 'sha512', + + CURRENT_TIME_FORMATTED: (): string => { + const now = new Date(); + const padString = (n: number) => n.toString().padStart(2, '0'); + return `${padString(now.getHours())}:${padString(now.getMinutes())}:${padString(now.getSeconds())}`; + }, + + ONE_WEEK_AGO: (): Date => { + const today = new Date(); + const oneWeekAgo = today.getDate() - 7; + today.setDate(oneWeekAgo); + return today; + }, + + ONE_MONTH_AND_A_WEEK_AGO: (): Date => { + const today = new Date(); + const oneMonthAgo = today.getMonth() - 1; + const oneWeekAgo = today.getDate() - 7; + today.setMonth(oneMonthAgo); + today.setDate(oneWeekAgo); + return today; + }, + + TWO_WEEKS_AGO: (): Date => { + const currentDate = Date.now(); + const twoWeeksInMs = 1209600000; + const dateTwoWeeksAgoInMs = currentDate - twoWeeksInMs; + return new Date(dateTwoWeeksAgoInMs); + }, + + ONE_DAY_AGO: (): Date => { + return new Date(Date.now() - 24 * 60 * 60 * 1000); + }, + + CRON_SHEDULE: '30 5 13 * * *', + COUNT_QUERY_TIMEOUT_MS: 2000, + EMAIL_VALIDATION_TIMEOUT: 1000, + + DEFAULT_PAGINATION: { page: 1, perPage: 20 }, + + LARGE_DATASET_ROW_LIMIT: 100000, + + DEFAULT_SLACK_CHANNEL: '#errors', + EXCEPTIONS_CHANNELS: '#errors', + KEEP_ALIVE_INTERVAL: 30000, + KEEP_ALIVE_COUNT_MAX: 120, + + DEFAULT_CONNECTION_CACHE_OPTIONS: { + max: 150, + ttl: 1000 * 60 * 60, + updateAgeOnGet: false, + updateAgeOnHas: false, + dispose: async (knex: Knex) => { + await knex.destroy(); + }, + }, + + DEFAULT_INVITATION_CACHE_OPTIONS: { + max: 200, + ttl: 1000 * 60 * 60, + }, + + DEFAULT_TABLE_PERMISSIONS_CACHE_OPTIONS: { + max: 1000, + ttl: 1000 * 10, + }, + + DEFAULT_FORWARD_IN_HOST: '127.0.0.1', + AUTOCOMPLETE_ROW_LIMIT: 20, + + FOREIGN_KEY_FIELDS: ['referenced_column_name', 'referenced_table_name', 'constraint_name', 'column_name'], + + TEST_CONNECTION_TO_POSTGRES: { + title: 'Postgres', + masterEncryption: false, + type: ConnectionTypesEnum.postgres, + username: getProcessVariable('POSTGRES_CONNECTION_USERNAME') || null, + password: getProcessVariable('POSTGRES_CONNECTION_PASSWORD') || null, + host: getProcessVariable('POSTGRES_CONNECTION_HOST') || null, + port: parseInt(getProcessVariable('POSTGRES_CONNECTION_PORT'), 10) || null, + database: getProcessVariable('POSTGRES_CONNECTION_DATABASE') || null, + isTestConnection: true, + }, + + TEST_CONNECTION_TO_MSSQL: { + title: 'MSSQL', + masterEncryption: false, + type: ConnectionTypesEnum.mssql, + host: getProcessVariable('MSSQL_CONNECTION_HOST') || null, + port: parseInt(getProcessVariable('MSSQL_CONNECTION_PORT'), 10) || null, + password: getProcessVariable('MSSQL_CONNECTION_PASSWORD') || null, + username: getProcessVariable('MSSQL_CONNECTION_USERNAME') || null, + database: getProcessVariable('MSSQL_CONNECTION_DATABASE') || null, + ssh: false, + ssl: false, + isTestConnection: true, + }, + + TEST_CONNECTION_TO_ORACLE: { + title: 'Oracle', + type: ConnectionTypesEnum.oracledb, + host: getProcessVariable('ORACLE_CONNECTION_HOST') || null, + port: parseInt(getProcessVariable('ORACLE_CONNECTION_PORT'), 10) || null, + username: getProcessVariable('ORACLE_CONNECTION_USERNAME') || null, + password: getProcessVariable('ORACLE_CONNECTION_PASSWORD') || null, + database: getProcessVariable('ORACLE_CONNECTION_DATABASE') || null, + sid: getProcessVariable('ORACLE_CONNECTION_SID') || null, + isTestConnection: true, + }, + + TEST_SSH_CONNECTION_TO_MYSQL: { + title: 'MySQL', + type: ConnectionTypesEnum.mysql, + host: getProcessVariable('MYSQL_CONNECTION_HOST') || null, + port: parseInt(getProcessVariable('MYSQL_CONNECTION_PORT'), 10) || null, + username: getProcessVariable('MYSQL_CONNECTION_USERNAME') || null, + password: getProcessVariable('MYSQL_CONNECTION_PASSWORD') || null, + database: getProcessVariable('MYSQL_CONNECTION_DATABASE') || null, + ssh: true, + isTestConnection: true, + sshHost: getProcessVariable('MYSQL_CONNECTION_SSH_HOST') || null, + sshPort: getProcessVariable('MYSQL_CONNECTION_SSH_PORT') || null, + sshUsername: getProcessVariable('MYSQL_CONNECTION_SSH_USERNAME') || null, + privateSSHKey: getProcessVariable('MYSQL_CONNECTION_SSH_KEY') || null, + }, + + TEST_CONNECTION_TO_MONGO: { + title: 'MongoDB', + type: ConnectionTypesEnum.mongodb, + host: getProcessVariable('MONGO_CONNECTION_HOST') || null, + port: parseInt(getProcessVariable('MONGO_CONNECTION_PORT'), 10) || null, + username: getProcessVariable('MONGO_CONNECTION_USERNAME') || null, + password: getProcessVariable('MONGO_CONNECTION_PASSWORD') || null, + database: getProcessVariable('MONGO_CONNECTION_DATABASE') || null, + authSource: getProcessVariable('MONGO_CONNECTION_AUTH_SOURCE') || null, + isTestConnection: true, + }, + + TEST_CONNECTION_TO_IBMBD2: { + title: 'IBM DB2', + type: ConnectionTypesEnum.ibmdb2, + host: getProcessVariable('IBM_DB2_CONNECTION_HOST') || null, + port: parseInt(getProcessVariable('IBM_DB2_CONNECTION_PORT'), 10) || null, + username: getProcessVariable('IBM_DB2_CONNECTION_USERNAME') || null, + password: getProcessVariable('IBM_DB2_CONNECTION_PASSWORD') || null, + database: getProcessVariable('IBM_DB2_CONNECTION_DATABASE') || null, + schema: getProcessVariable('IBM_DB2_CONNECTION_SCHEMA') || null, + isTestConnection: true, + }, + + REMOVED_PASSWORD_VALUE: '***', + REMOVED_SENSITIVE_FIELD_IF_CHANGED: '* * * sensitive data, no logs stored * * *', + REMOVED_SENSITIVE_FIELD_IF_NOT_CHANGED: '', + + getTestConnectionsArr: (): Array => { + const isSaaS = process.env.IS_SAAS; + if (!isSaaS || isSaaS !== 'true') { + return []; + } + const testConnections: Array = Constants.getTestConnectionsFromDSN() || []; + if (!testConnections.length) { + testConnections.push( + Constants.TEST_CONNECTION_TO_ORACLE as CreateConnectionDto, + Constants.TEST_CONNECTION_TO_POSTGRES as CreateConnectionDto, + Constants.TEST_SSH_CONNECTION_TO_MYSQL as unknown as CreateConnectionDto, + Constants.TEST_CONNECTION_TO_MSSQL as CreateConnectionDto, + Constants.TEST_CONNECTION_TO_MONGO as CreateConnectionDto, + Constants.TEST_CONNECTION_TO_IBMBD2 as CreateConnectionDto, + ); + } + + return testConnections.filter((dto) => { + const values = Object.values(dto); + const nullElementIndex = values.indexOf(null); + return nullElementIndex < 0; + }); + }, + + getTestConnectionsFromDSN: (): Array => { + if (!isSaaS()) { + return []; + } + const testConnectionsJSON = getProcessVariable('TEST_CONNECTIONS'); + if (!testConnectionsJSON) { + return null; + } + try { + const testConnectionsDSNFromJSON: TestConnectionsFromJSON = JSON.parse(testConnectionsJSON); + const testConnectionsArr: Array = []; + for (const [connection_type, connection_string] of Object.entries(testConnectionsDSNFromJSON)) { + let connection: CreateConnectionDto | null = null; + const type = connection_type.toLowerCase(); + switch (true) { + case type.toLowerCase().includes('mysql'): + connection = parseTestMySQLConnectionString(connection_string) as CreateConnectionDto; + break; + case type.toLowerCase().includes('postgres'): + connection = parseTestPostgresConnectionString(connection_string) as CreateConnectionDto; + break; + case type.toLowerCase().includes('mssql'): + connection = parseTestMSSQLConnectionString(connection_string) as CreateConnectionDto; + break; + case type.toLowerCase().includes('oracle'): + connection = parseTestOracleDBConnectionString(connection_string) as CreateConnectionDto; + break; + case type.toLowerCase().includes('mongo'): + connection = parseTestMongoDBConnectionString(connection_string) as CreateConnectionDto; + break; + // case type.toLowerCase().includes('ibmdb2'): + // connection = parseTestIbmDB2ConnectionString(connection_string) as CreateConnectionDto; + // break; + case type.toLowerCase().includes('dynamodb'): + connection = parseTestDynamoDBConnectionString(connection_string) as CreateConnectionDto; + break; + default: + break; + } + if (connection) { + testConnectionsArr.push(connection); + } + } + return testConnectionsArr; + } catch (e) { + console.error('Error parsing test connections from DSN: ' + e); + return null; + } + }, + + getTestConnectionsHostNamesArr: function (): Array { + return this.getTestConnectionsArr().map((connection) => connection.host); + }, + + APP_DOMAIN_ADDRESS: process.env.APP_DOMAIN_ADDRESS || `http://127.0.0.1:3000`, + ALLOWED_REQUEST_DOMAIN: (): string => { + if (isTest()) { + return Constants.APP_DOMAIN_ADDRESS; + } + return `app.rocketadmin.com`; + }, + + APP_REQUEST_DOMAINS(): Array { + const allowedDomains = ['app.rocketadmin.com', 'saas.rocketadmin.com', Constants.APP_DOMAIN_ADDRESS]; + if (isTest()) { + allowedDomains.push('127.0.0.1', Constants.APP_DOMAIN_ADDRESS); + } + return allowedDomains; + }, + + AUTOADMIN_SUPPORT_MAIL: 'support@autoadmin.org', }; diff --git a/backend/src/helpers/enum-to-string.ts b/backend/src/helpers/enum-to-string.ts index cf0125a64..93e5f42bc 100644 --- a/backend/src/helpers/enum-to-string.ts +++ b/backend/src/helpers/enum-to-string.ts @@ -1,3 +1,3 @@ export function enumToString(en: any): string { - return Object.values(en).join(', '); + return Object.values(en).join(', '); } diff --git a/backend/src/helpers/get-master-password.ts b/backend/src/helpers/get-master-password.ts index 4bab94791..89fedbcdb 100644 --- a/backend/src/helpers/get-master-password.ts +++ b/backend/src/helpers/get-master-password.ts @@ -1,6 +1,6 @@ import { IRequestWithCognitoInfo } from '../authorization/index.js'; export function getMasterPwd(request: IRequestWithCognitoInfo): string | null { - const masterPwd = request.headers.masterpwd; - return masterPwd ? masterPwd as string : null; + const masterPwd = request.headers.masterpwd; + return masterPwd ? (masterPwd as string) : null; } diff --git a/backend/src/helpers/get-process-variable.ts b/backend/src/helpers/get-process-variable.ts index 9a3b5c548..b8dc8c1ff 100644 --- a/backend/src/helpers/get-process-variable.ts +++ b/backend/src/helpers/get-process-variable.ts @@ -1,4 +1,4 @@ export function getProcessVariable(variableName: string): string | null { - // eslint-disable-next-line security/detect-object-injection - return process.env[variableName] ? process.env[variableName] : null; + // eslint-disable-next-line security/detect-object-injection + return process.env[variableName] ? process.env[variableName] : null; } diff --git a/backend/src/helpers/get-property-value-by-descriptor.ts b/backend/src/helpers/get-property-value-by-descriptor.ts index 520c8c7cf..d346603b0 100644 --- a/backend/src/helpers/get-property-value-by-descriptor.ts +++ b/backend/src/helpers/get-property-value-by-descriptor.ts @@ -1,3 +1,3 @@ export function getPropertyValueByDescriptor(obj: T, propName: string): any { - return Object.getOwnPropertyDescriptor(obj, propName).value; + return Object.getOwnPropertyDescriptor(obj, propName).value; } diff --git a/backend/src/helpers/get-uniq-array-strings.ts b/backend/src/helpers/get-uniq-array-strings.ts index 4a4e051a1..c265deede 100644 --- a/backend/src/helpers/get-uniq-array-strings.ts +++ b/backend/src/helpers/get-uniq-array-strings.ts @@ -1,3 +1,3 @@ export function getUniqArrayStrings(array: Array): Array { - return Array.from(new Set(array)); + return Array.from(new Set(array)); } diff --git a/backend/src/helpers/index.ts b/backend/src/helpers/index.ts index b81d0cf32..04e30e57b 100644 --- a/backend/src/helpers/index.ts +++ b/backend/src/helpers/index.ts @@ -4,9 +4,8 @@ export { compareArrayElements } from './compare-array-elements.js'; export { getMasterPwd } from './get-master-password.js'; export { getPropertyValueByDescriptor } from './get-property-value-by-descriptor.js'; export { getUniqArrayStrings } from './get-uniq-array-strings.js'; -export { getValuesBetweenCurlies } from './operate-values-between-curlies.js'; export { isConnectionEntityAgent, isConnectionTypeAgent } from './is-connection-entity-agent.js'; export { isObjectEmpty } from './is-object-empty.js'; -export { replaceTextInCurlies } from './operate-values-between-curlies.js'; +export { getValuesBetweenCurlies, replaceTextInCurlies } from './operate-values-between-curlies.js'; export { slackPostMessage } from './slack/slack-post-message.js'; export { toPrettyErrorsMsg } from './to-pretty-errors-msg.js'; diff --git a/backend/src/helpers/is-connection-entity-agent.ts b/backend/src/helpers/is-connection-entity-agent.ts index 4b19199f2..99709e18e 100644 --- a/backend/src/helpers/is-connection-entity-agent.ts +++ b/backend/src/helpers/is-connection-entity-agent.ts @@ -1,38 +1,38 @@ import { - ConnectionTypesEnum, - ConnectionTypeTestEnum, + ConnectionTypesEnum, + ConnectionTypeTestEnum, } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; import { CreateConnectionDto } from '../entities/connection/application/dto/create-connection.dto.js'; import { ConnectionEntity } from '../entities/connection/connection.entity.js'; export function isConnectionEntityAgent(connection: ConnectionEntity | CreateConnectionDto): boolean { - const agentTypes = [ - ConnectionTypesEnum.agent_postgres, - ConnectionTypesEnum.agent_mysql, - ConnectionTypesEnum.agent_oracledb, - ConnectionTypesEnum.agent_mssql, - ConnectionTypesEnum.agent_ibmdb2, - ConnectionTypesEnum.agent_mongodb, - ConnectionTypesEnum.agent_cassandra, - ConnectionTypesEnum.agent_redis, - ConnectionTypesEnum.agent_clickhouse, - ]; + const agentTypes = [ + ConnectionTypesEnum.agent_postgres, + ConnectionTypesEnum.agent_mysql, + ConnectionTypesEnum.agent_oracledb, + ConnectionTypesEnum.agent_mssql, + ConnectionTypesEnum.agent_ibmdb2, + ConnectionTypesEnum.agent_mongodb, + ConnectionTypesEnum.agent_cassandra, + ConnectionTypesEnum.agent_redis, + ConnectionTypesEnum.agent_clickhouse, + ]; - return agentTypes.includes(connection.type as ConnectionTypesEnum); + return agentTypes.includes(connection.type as ConnectionTypesEnum); } export function isConnectionTypeAgent(type: ConnectionTypesEnum | string): boolean { - const connectionTypes = [ - ConnectionTypeTestEnum.agent_postgres, - ConnectionTypeTestEnum.agent_mysql, - ConnectionTypeTestEnum.agent_oracledb, - ConnectionTypeTestEnum.agent_mssql, - ConnectionTypeTestEnum.agent_ibmdb2, - ConnectionTypeTestEnum.agent_mongodb, - ConnectionTypeTestEnum.agent_cassandra, - ConnectionTypesEnum.agent_redis, - ConnectionTypesEnum.agent_clickhouse, - ]; + const connectionTypes = [ + ConnectionTypeTestEnum.agent_postgres, + ConnectionTypeTestEnum.agent_mysql, + ConnectionTypeTestEnum.agent_oracledb, + ConnectionTypeTestEnum.agent_mssql, + ConnectionTypeTestEnum.agent_ibmdb2, + ConnectionTypeTestEnum.agent_mongodb, + ConnectionTypeTestEnum.agent_cassandra, + ConnectionTypesEnum.agent_redis, + ConnectionTypesEnum.agent_clickhouse, + ]; - return connectionTypes.includes(type as ConnectionTypeTestEnum); + return connectionTypes.includes(type as ConnectionTypeTestEnum); } diff --git a/backend/src/helpers/is-object-empty.ts b/backend/src/helpers/is-object-empty.ts index 795948237..1ec19d280 100644 --- a/backend/src/helpers/is-object-empty.ts +++ b/backend/src/helpers/is-object-empty.ts @@ -1,9 +1,9 @@ export function isObjectEmpty(obj: any): boolean { - if (!obj) { - return true; - } - for (const _ in obj) { - return false; - } - return true; + if (!obj) { + return true; + } + for (const _ in obj) { + return false; + } + return true; } diff --git a/backend/src/helpers/operate-values-between-curlies.ts b/backend/src/helpers/operate-values-between-curlies.ts index d14424412..18a9e151f 100644 --- a/backend/src/helpers/operate-values-between-curlies.ts +++ b/backend/src/helpers/operate-values-between-curlies.ts @@ -1,23 +1,23 @@ import { safeRegex } from 'safe-regex2'; export function getValuesBetweenCurlies(str: string): Array { - const valuesArr = []; - const regExp = /{{([^}}]+)}}/g; - let tmpText: RegExpExecArray; - while ((tmpText = regExp.exec(str))) { - valuesArr.push(tmpText[1]); - } - return valuesArr; + const valuesArr = []; + const regExp = /{{([^}}]+)}}/g; + let tmpText: RegExpExecArray; + while ((tmpText = regExp.exec(str))) { + valuesArr.push(tmpText[1]); + } + return valuesArr; } export function replaceTextInCurlies(str: string, replaceArr: Array, replaceWithArr: Array): string { - for (let i = 0; i < replaceArr.length; i++) { - // added safe regexp check - // eslint-disable-next-line security/detect-non-literal-regexp - const regExp = new RegExp('{{' + replaceArr.at(i) + '}}', 'gi'); - if (safeRegex(regExp)) { - str = str.replace(regExp, replaceWithArr.at(i)); - } - } - return str; + for (let i = 0; i < replaceArr.length; i++) { + // added safe regexp check + // eslint-disable-next-line security/detect-non-literal-regexp + const regExp = new RegExp('{{' + replaceArr.at(i) + '}}', 'gi'); + if (safeRegex(regExp)) { + str = str.replace(regExp, replaceWithArr.at(i)); + } + } + return str; } diff --git a/backend/src/helpers/parsers/string-connection-to-database-parsers.ts b/backend/src/helpers/parsers/string-connection-to-database-parsers.ts index 1f767b261..54a56f8e8 100644 --- a/backend/src/helpers/parsers/string-connection-to-database-parsers.ts +++ b/backend/src/helpers/parsers/string-connection-to-database-parsers.ts @@ -3,162 +3,162 @@ import { CreateConnectionDto } from '../../entities/connection/application/dto/c // postgresql://user:password@localhost:5432/mydatabase?ssh=true&privateSSHKey=key&sshHost=sshHost&sshPort=22&sshUsername=sshUser&ssl=true&cert=cert export const parseTestPostgresConnectionString = (connectionString: string): Partial => { - const url = new URL(connectionString); - const config: Partial = {}; - config.host = url.hostname || null; - config.port = parseInt(url.port, 10) || 5432; - config.username = url.username || null; - config.password = url.password || null; - config.database = url.pathname.split('/')[1] || null; - config.schema = 'public'; - config.type = ConnectionTypesEnum.postgres; - config.title = 'School of fish'; - config.isTestConnection = true; - config.ssh = url.searchParams.get('ssh') === 'true'; - config.privateSSHKey = url.searchParams.get('privateSSHKey') || undefined; - config.sshHost = url.searchParams.get('sshHost') || undefined; - config.sshPort = parseInt(url.searchParams.get('sshPort'), 10) || undefined; - config.sshUsername = url.searchParams.get('sshUsername') || undefined; - config.ssl = url.searchParams.get('ssl') === 'true'; - config.cert = url.searchParams.get('cert') || undefined; - return config; + const url = new URL(connectionString); + const config: Partial = {}; + config.host = url.hostname || null; + config.port = parseInt(url.port, 10) || 5432; + config.username = url.username || null; + config.password = url.password || null; + config.database = url.pathname.split('/')[1] || null; + config.schema = 'public'; + config.type = ConnectionTypesEnum.postgres; + config.title = 'School of fish'; + config.isTestConnection = true; + config.ssh = url.searchParams.get('ssh') === 'true'; + config.privateSSHKey = url.searchParams.get('privateSSHKey') || undefined; + config.sshHost = url.searchParams.get('sshHost') || undefined; + config.sshPort = parseInt(url.searchParams.get('sshPort'), 10) || undefined; + config.sshUsername = url.searchParams.get('sshUsername') || undefined; + config.ssl = url.searchParams.get('ssl') === 'true'; + config.cert = url.searchParams.get('cert') || undefined; + return config; }; // mysql://user:password@localhost:3306/mydatabase?ssh=true&privateSSHKey=key&sshHost=sshHost&sshPort=22&sshUsername=sshUser&ssl=true&cert=cert export const parseTestMySQLConnectionString = (connectionString: string): Partial => { - const url = new URL(connectionString); - const config: Partial = {}; - config.host = url.hostname || null; - config.port = parseInt(url.port, 10) || 3306; - config.username = url.username || null; - config.password = url.password || null; - config.database = url.pathname.split('/')[1] || null; - config.type = ConnectionTypesEnum.mysql || null; - config.title = 'Coworking hub'; - config.isTestConnection = true; - config.ssh = url.searchParams.get('ssh') === 'true'; - config.privateSSHKey = url.searchParams.get('privateSSHKey') || undefined; - config.sshHost = url.searchParams.get('sshHost') || undefined; - config.sshPort = parseInt(url.searchParams.get('sshPort'), 10) || undefined; - config.sshUsername = url.searchParams.get('sshUsername') || undefined; - config.ssl = url.searchParams.get('ssl') === 'true'; - config.cert = url.searchParams.get('cert') || undefined; - return config; + const url = new URL(connectionString); + const config: Partial = {}; + config.host = url.hostname || null; + config.port = parseInt(url.port, 10) || 3306; + config.username = url.username || null; + config.password = url.password || null; + config.database = url.pathname.split('/')[1] || null; + config.type = ConnectionTypesEnum.mysql || null; + config.title = 'Coworking hub'; + config.isTestConnection = true; + config.ssh = url.searchParams.get('ssh') === 'true'; + config.privateSSHKey = url.searchParams.get('privateSSHKey') || undefined; + config.sshHost = url.searchParams.get('sshHost') || undefined; + config.sshPort = parseInt(url.searchParams.get('sshPort'), 10) || undefined; + config.sshUsername = url.searchParams.get('sshUsername') || undefined; + config.ssl = url.searchParams.get('ssl') === 'true'; + config.cert = url.searchParams.get('cert') || undefined; + return config; }; // mssql://user:password@localhost:1433/mydatabase?ssh=true&privateSSHKey=key&sshHost=sshHost&sshPort=22&sshUsername=sshUser&ssl=true&cert=cert&azure_encryption=true export const parseTestMSSQLConnectionString = (connectionString: string): Partial => { - const url = new URL(connectionString); - const config: Partial = {}; - config.host = url.hostname || null; - config.port = parseInt(url.port, 10) || 1433; - config.username = url.username || null; - config.password = url.password || null; - config.database = url.pathname.split('/')[1] || null; - config.type = ConnectionTypesEnum.mssql; - config.title = 'Online shop'; - config.isTestConnection = true; - config.ssh = url.searchParams.get('ssh') === 'true'; - config.privateSSHKey = url.searchParams.get('privateSSHKey') || undefined; - config.sshHost = url.searchParams.get('sshHost') || undefined; - config.sshPort = parseInt(url.searchParams.get('sshPort'), 10) || undefined; - config.sshUsername = url.searchParams.get('sshUsername') || undefined; - config.ssl = url.searchParams.get('ssl') === 'true'; - config.cert = url.searchParams.get('cert') || undefined; - config.schema = url.searchParams.get('schema') || undefined; - config.azure_encryption = url.searchParams.get('azure_encryption') === 'true'; - return config; + const url = new URL(connectionString); + const config: Partial = {}; + config.host = url.hostname || null; + config.port = parseInt(url.port, 10) || 1433; + config.username = url.username || null; + config.password = url.password || null; + config.database = url.pathname.split('/')[1] || null; + config.type = ConnectionTypesEnum.mssql; + config.title = 'Online shop'; + config.isTestConnection = true; + config.ssh = url.searchParams.get('ssh') === 'true'; + config.privateSSHKey = url.searchParams.get('privateSSHKey') || undefined; + config.sshHost = url.searchParams.get('sshHost') || undefined; + config.sshPort = parseInt(url.searchParams.get('sshPort'), 10) || undefined; + config.sshUsername = url.searchParams.get('sshUsername') || undefined; + config.ssl = url.searchParams.get('ssl') === 'true'; + config.cert = url.searchParams.get('cert') || undefined; + config.schema = url.searchParams.get('schema') || undefined; + config.azure_encryption = url.searchParams.get('azure_encryption') === 'true'; + return config; }; // oracle://user:password@localhost:1521/orcl?database=mydatabase&ssh=true&privateSSHKey=key&sshHost=sshHost&sshPort=22&sshUsername=sshUser&ssl=true&cert=cert export const parseTestOracleDBConnectionString = (connectionString: string): Partial => { - const url = new URL(connectionString); - const config: Partial = {}; - config.host = url.hostname || null; - config.port = parseInt(url.port, 10) || 1521; - config.username = url.username || null; - config.password = url.password || null; - config.sid = url.pathname.split('/')[1] || null; - const params = new URLSearchParams(url.search); - config.database = params.get('database') || undefined; - config.type = ConnectionTypesEnum.oracledb; - config.title = 'Online shop'; - config.isTestConnection = true; - config.schema = params.get('schema') || undefined; - config.ssh = params.get('ssh') === 'true'; - config.privateSSHKey = params.get('privateSSHKey') || undefined; - config.sshHost = params.get('sshHost') || undefined; - config.sshPort = parseInt(params.get('sshPort'), 10) || undefined; - config.sshUsername = params.get('sshUsername') || undefined; - config.ssl = params.get('ssl') === 'true'; - config.cert = params.get('cert') || undefined; - return config; + const url = new URL(connectionString); + const config: Partial = {}; + config.host = url.hostname || null; + config.port = parseInt(url.port, 10) || 1521; + config.username = url.username || null; + config.password = url.password || null; + config.sid = url.pathname.split('/')[1] || null; + const params = new URLSearchParams(url.search); + config.database = params.get('database') || undefined; + config.type = ConnectionTypesEnum.oracledb; + config.title = 'Online shop'; + config.isTestConnection = true; + config.schema = params.get('schema') || undefined; + config.ssh = params.get('ssh') === 'true'; + config.privateSSHKey = params.get('privateSSHKey') || undefined; + config.sshHost = params.get('sshHost') || undefined; + config.sshPort = parseInt(params.get('sshPort'), 10) || undefined; + config.sshUsername = params.get('sshUsername') || undefined; + config.ssl = params.get('ssl') === 'true'; + config.cert = params.get('cert') || undefined; + return config; }; // mongodb://username:password@host:port/mydb?authSource=admin&ssh=true&privateSSHKey=key&sshHost=sshHost&sshPort=22&sshUsername=sshUser&ssl=true&cert=cert export const parseTestMongoDBConnectionString = (connectionString: string): Partial => { - const url = new URL(connectionString); - const config: Partial = {}; - config.host = url.hostname || null; - config.port = parseInt(url.port, 10) || 27017; - config.username = url.username || null; - config.password = url.password || null; - config.database = url.pathname.split('/')[1] || null; - config.type = ConnectionTypesEnum.mongodb; - config.title = 'Movie theater'; - const authSource = url.searchParams.get('authSource'); - if (authSource) { - config.authSource = authSource; - } - config.isTestConnection = true; - config.ssh = url.searchParams.get('ssh') === 'true'; - config.privateSSHKey = url.searchParams.get('privateSSHKey') || undefined; - config.sshHost = url.searchParams.get('sshHost') || undefined; - config.sshPort = parseInt(url.searchParams.get('sshPort'), 10) || undefined; - config.sshUsername = url.searchParams.get('sshUsername') || undefined; - config.ssl = url.searchParams.get('ssl') === 'true'; - config.cert = url.searchParams.get('cert') || undefined; - return config; + const url = new URL(connectionString); + const config: Partial = {}; + config.host = url.hostname || null; + config.port = parseInt(url.port, 10) || 27017; + config.username = url.username || null; + config.password = url.password || null; + config.database = url.pathname.split('/')[1] || null; + config.type = ConnectionTypesEnum.mongodb; + config.title = 'Movie theater'; + const authSource = url.searchParams.get('authSource'); + if (authSource) { + config.authSource = authSource; + } + config.isTestConnection = true; + config.ssh = url.searchParams.get('ssh') === 'true'; + config.privateSSHKey = url.searchParams.get('privateSSHKey') || undefined; + config.sshHost = url.searchParams.get('sshHost') || undefined; + config.sshPort = parseInt(url.searchParams.get('sshPort'), 10) || undefined; + config.sshUsername = url.searchParams.get('sshUsername') || undefined; + config.ssl = url.searchParams.get('ssl') === 'true'; + config.cert = url.searchParams.get('cert') || undefined; + return config; }; // db2://user:password@localhost:50000/mydatabase?schema=myschema&ssh=true&privateSSHKey=key&sshHost=sshHost&sshPort=22&sshUsername=sshUser&ssl=true&cert=cert export const parseTestIbmDB2ConnectionString = (connectionString: string): Partial => { - const url = new URL(connectionString); - const config: Partial = {}; - config.host = url.hostname || null; - config.port = parseInt(url.port, 10) || 50000; - config.username = url.username || null; - config.password = url.password || null; - config.database = url.pathname.split('/')[1] || null; - const params = new URLSearchParams(url.search); - config.schema = params.get('schema') || undefined; - config.type = ConnectionTypesEnum.ibmdb2; - config.title = 'IBM DB2'; - config.isTestConnection = true; - config.ssh = params.get('ssh') === 'true'; - config.privateSSHKey = params.get('privateSSHKey') || undefined; - config.sshHost = params.get('sshHost') || undefined; - config.sshPort = parseInt(params.get('sshPort'), 10) || undefined; - config.sshUsername = params.get('sshUsername') || undefined; - config.ssl = params.get('ssl') === 'true'; - config.cert = params.get('cert') || undefined; - return config; + const url = new URL(connectionString); + const config: Partial = {}; + config.host = url.hostname || null; + config.port = parseInt(url.port, 10) || 50000; + config.username = url.username || null; + config.password = url.password || null; + config.database = url.pathname.split('/')[1] || null; + const params = new URLSearchParams(url.search); + config.schema = params.get('schema') || undefined; + config.type = ConnectionTypesEnum.ibmdb2; + config.title = 'IBM DB2'; + config.isTestConnection = true; + config.ssh = params.get('ssh') === 'true'; + config.privateSSHKey = params.get('privateSSHKey') || undefined; + config.sshHost = params.get('sshHost') || undefined; + config.sshPort = parseInt(params.get('sshPort'), 10) || undefined; + config.sshUsername = params.get('sshUsername') || undefined; + config.ssl = params.get('ssl') === 'true'; + config.cert = params.get('cert') || undefined; + return config; }; // dynamodb://accessKeyId:secretAccessKey@localhost:8000/ export const parseTestDynamoDBConnectionString = (connectionString: string): Partial => { - const modifiedConnectionString = connectionString.replace('dynamodb://', ''); - const [credentials, nestedUrl] = modifiedConnectionString.split('@'); - const [username, password] = credentials.split(':'); - const url = new URL(nestedUrl); - const config: Partial = {}; - config.username = username || null; - config.password = password || null; - const host = `${url.protocol}//${url.hostname}:${url.port}`; - config.host = host; - config.type = ConnectionTypesEnum.dynamodb; - config.title = 'Orders'; - config.isTestConnection = true; - config.ssl = false; - return config; + const modifiedConnectionString = connectionString.replace('dynamodb://', ''); + const [credentials, nestedUrl] = modifiedConnectionString.split('@'); + const [username, password] = credentials.split(':'); + const url = new URL(nestedUrl); + const config: Partial = {}; + config.username = username || null; + config.password = password || null; + const host = `${url.protocol}//${url.hostname}:${url.port}`; + config.host = host; + config.type = ConnectionTypesEnum.dynamodb; + config.title = 'Orders'; + config.isTestConnection = true; + config.ssl = false; + return config; }; diff --git a/backend/src/helpers/slack/action-slack-post-message.ts b/backend/src/helpers/slack/action-slack-post-message.ts index 277ac7a93..b946d0e42 100644 --- a/backend/src/helpers/slack/action-slack-post-message.ts +++ b/backend/src/helpers/slack/action-slack-post-message.ts @@ -1,8 +1,8 @@ import axios from 'axios'; export async function actionSlackPostMessage(message: string, slack_url: string): Promise { - if (!slack_url || !message) { - return; - } - await axios.post(slack_url, { text: message }); + if (!slack_url || !message) { + return; + } + await axios.post(slack_url, { text: message }); } diff --git a/backend/src/helpers/slack/slack-post-message.ts b/backend/src/helpers/slack/slack-post-message.ts index 5ed76884c..fa4a48906 100644 --- a/backend/src/helpers/slack/slack-post-message.ts +++ b/backend/src/helpers/slack/slack-post-message.ts @@ -2,22 +2,22 @@ import axios from 'axios'; import { Constants } from '../constants/constants.js'; export async function slackPostMessage(message: string, channel = Constants.DEFAULT_SLACK_CHANNEL): Promise { - try { - const slackBotToken = process.env.SLACK_BOT_ACCESS_TOKEN; - if (process.env.NODE_ENV === 'test' || !slackBotToken) { - return; - } - const url = 'https://slack.com/api/chat.postMessage'; - const res = await axios.post( - url, - { - channel: channel, - text: message, - }, - { headers: { authorization: `Bearer ${slackBotToken}` } }, - ); - return res.data; - } catch (_e) { - return; - } + try { + const slackBotToken = process.env.SLACK_BOT_ACCESS_TOKEN; + if (process.env.NODE_ENV === 'test' || !slackBotToken) { + return; + } + const url = 'https://slack.com/api/chat.postMessage'; + const res = await axios.post( + url, + { + channel: channel, + text: message, + }, + { headers: { authorization: `Bearer ${slackBotToken}` } }, + ); + return res.data; + } catch (_e) { + return; + } } diff --git a/backend/src/helpers/to-pretty-errors-msg.ts b/backend/src/helpers/to-pretty-errors-msg.ts index 55a470e66..597dd7244 100644 --- a/backend/src/helpers/to-pretty-errors-msg.ts +++ b/backend/src/helpers/to-pretty-errors-msg.ts @@ -1,3 +1,3 @@ export function toPrettyErrorsMsg(errorArray: Array): string { - return errorArray.join(', ').trim(); + return errorArray.join(', ').trim(); } diff --git a/backend/src/helpers/validators/is-action-url-host-allowed.ts b/backend/src/helpers/validators/is-action-url-host-allowed.ts index 4cf75cc0b..2ef22ce08 100644 --- a/backend/src/helpers/validators/is-action-url-host-allowed.ts +++ b/backend/src/helpers/validators/is-action-url-host-allowed.ts @@ -1,7 +1,7 @@ import dns from 'dns'; import ipRangeCheck from 'ip-range-check'; -import { Constants } from '../constants/constants.js'; import { isSaaS } from '../app/is-saas.js'; +import { Constants } from '../constants/constants.js'; export async function isActionUrlHostAllowed(url: string): Promise { if (process.env.NODE_ENV === 'test') { diff --git a/backend/src/helpers/validators/is-object-property-exists-validator.ts b/backend/src/helpers/validators/is-object-property-exists-validator.ts index f93daa087..781450c13 100644 --- a/backend/src/helpers/validators/is-object-property-exists-validator.ts +++ b/backend/src/helpers/validators/is-object-property-exists-validator.ts @@ -1,6 +1,6 @@ export function isObjectPropertyExists(obj: unknown, property: string): boolean { - if (!obj || typeof obj !== 'object') { - return false; - } - return Object.hasOwn(obj, property); + if (!obj || typeof obj !== 'object') { + return false; + } + return Object.hasOwn(obj, property); } diff --git a/backend/src/helpers/validators/required-environment-variables.validator.ts b/backend/src/helpers/validators/required-environment-variables.validator.ts index ed06400f2..c8fe67bea 100644 --- a/backend/src/helpers/validators/required-environment-variables.validator.ts +++ b/backend/src/helpers/validators/required-environment-variables.validator.ts @@ -1,30 +1,30 @@ import { Messages } from '../../exceptions/text/messages.js'; export function requiredEnvironmentVariablesValidator(): void { - const requiredParameterNames: Array = ['PRIVATE_KEY', 'JWT_SECRET']; + const requiredParameterNames: Array = ['PRIVATE_KEY', 'JWT_SECRET']; - const pgLiteFolderPath = getEnvironmentVariable('PGLITE_FOLDER_PATH'); - if (!pgLiteFolderPath) { - requiredParameterNames.push('DATABASE_URL'); - } + const pgLiteFolderPath = getEnvironmentVariable('PGLITE_FOLDER_PATH'); + if (!pgLiteFolderPath) { + requiredParameterNames.push('DATABASE_URL'); + } - const requiredParameters: Array<{ [k: string]: string | null }> = requiredParameterNames.map((paramName) => { - const paramValue = getEnvironmentVariable(paramName); - return { - [paramName]: paramValue, - }; - }); - const emptyRequiredParameterNames: Array = requiredParameters - .filter((param) => { - return !param[Object.keys(param)[0]]; - }) - .map((param) => Object.keys(param)[0]); - if (emptyRequiredParameterNames.length > 0) { - throw new Error(Messages.REQUIRED_PARAMETERS_MISSING(emptyRequiredParameterNames)); - } + const requiredParameters: Array<{ [k: string]: string | null }> = requiredParameterNames.map((paramName) => { + const paramValue = getEnvironmentVariable(paramName); + return { + [paramName]: paramValue, + }; + }); + const emptyRequiredParameterNames: Array = requiredParameters + .filter((param) => { + return !param[Object.keys(param)[0]]; + }) + .map((param) => Object.keys(param)[0]); + if (emptyRequiredParameterNames.length > 0) { + throw new Error(Messages.REQUIRED_PARAMETERS_MISSING(emptyRequiredParameterNames)); + } } function getEnvironmentVariable(key: string): string | null { - // eslint-disable-next-line security/detect-object-injection - return process.env[key] || null; + // eslint-disable-next-line security/detect-object-injection + return process.env[key] || null; } diff --git a/backend/src/helpers/validators/validate-string-with-enum.ts b/backend/src/helpers/validators/validate-string-with-enum.ts index edeebea73..435272ced 100644 --- a/backend/src/helpers/validators/validate-string-with-enum.ts +++ b/backend/src/helpers/validators/validate-string-with-enum.ts @@ -1,3 +1,3 @@ export function validateStringWithEnum(str: string, en: any): boolean { - return !!Object.values(en).find((value) => value === str); + return !!Object.values(en).find((value) => value === str); } diff --git a/backend/src/helpers/validators/validation-helper.ts b/backend/src/helpers/validators/validation-helper.ts index 87d016f4b..37469182d 100644 --- a/backend/src/helpers/validators/validation-helper.ts +++ b/backend/src/helpers/validators/validation-helper.ts @@ -1,111 +1,111 @@ import { BadRequestException, HttpException, HttpStatus } from '@nestjs/common'; +import countries from 'i18n-iso-countries'; import validator from 'validator'; import { Messages } from '../../exceptions/text/messages.js'; import { Constants } from '../constants/constants.js'; -import countries from 'i18n-iso-countries'; export class ValidationHelper { - public static isValidUrl(url: string): boolean { - return validator.isURL(url); - } + public static isValidUrl(url: string): boolean { + return validator.isURL(url); + } - public static isValidEmail(email: string): boolean { - return validator.isEmail(email); - } + public static isValidEmail(email: string): boolean { + return validator.isEmail(email); + } - public static isValidUUID(uuid: string): boolean { - return validator.isUUID(uuid); - } + public static isValidUUID(uuid: string): boolean { + return validator.isUUID(uuid); + } - public static isValidVerificationString(verificationString: string): boolean { - return validator.isWhitelisted(verificationString, Constants.VERIFICATION_STRING_WHITELIST()); - } + public static isValidVerificationString(verificationString: string): boolean { + return validator.isWhitelisted(verificationString, Constants.VERIFICATION_STRING_WHITELIST()); + } - public static isValidPhoneNumber(phoneNumber: string): boolean { - return validator.isMobilePhone(phoneNumber, 'any', { strictMode: false }); - } + public static isValidPhoneNumber(phoneNumber: string): boolean { + return validator.isMobilePhone(phoneNumber, 'any', { strictMode: false }); + } - public static isValidRgbColor(rgbColor: string): boolean { - return validator.isRgbColor(rgbColor); - } + public static isValidRgbColor(rgbColor: string): boolean { + return validator.isRgbColor(rgbColor); + } - public static isValidHexColor(hexColor: string): boolean { - return validator.isHexColor(hexColor); - } + public static isValidHexColor(hexColor: string): boolean { + return validator.isHexColor(hexColor); + } - public static isValidHslColor(hslColor: string): boolean { - return validator.isHSL(hslColor); - } + public static isValidHslColor(hslColor: string): boolean { + return validator.isHSL(hslColor); + } - public static isValidJSON(jsonString: string): boolean { - if (typeof jsonString !== 'string') { - return false; - } - validator.isJSON(jsonString); - } + public static isValidJSON(jsonString: string): boolean { + if (typeof jsonString !== 'string') { + return false; + } + validator.isJSON(jsonString); + } - public static isValidJWT(token: string): boolean { - return validator.isJWT(token); - } + public static isValidJWT(token: string): boolean { + return validator.isJWT(token); + } - public static isValidDomain(domain: string): boolean { - return validator.isFQDN(domain, { require_tld: true }); - } + public static isValidDomain(domain: string): boolean { + return validator.isFQDN(domain, { require_tld: true }); + } - public static isValidCountryCode(countryCode: string): boolean { - return countries.isValid(countryCode); - } + public static isValidCountryCode(countryCode: string): boolean { + return countries.isValid(countryCode); + } - public static validateOrThrowHttpExceptionEmail(email: string): boolean { - const isEmailValid = ValidationHelper.isValidEmail(email); - if (isEmailValid) { - return true; - } - throw new BadRequestException(Messages.EMAIL_INVALID); - } + public static validateOrThrowHttpExceptionEmail(email: string): boolean { + const isEmailValid = ValidationHelper.isValidEmail(email); + if (isEmailValid) { + return true; + } + throw new BadRequestException(Messages.EMAIL_INVALID); + } - public static isValidNanoId(id: string): boolean { - if (typeof id !== 'string') { - return false; - } - const validChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'; - if (id.length !== 8) { - return false; - } - for (let i = 0; i < id.length; i++) { - if (!validChars.includes(id.at(i))) { - return false; - } - } - return true; - } + public static isValidNanoId(id: string): boolean { + if (typeof id !== 'string') { + return false; + } + const validChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_'; + if (id.length !== 8) { + return false; + } + for (let i = 0; i < id.length; i++) { + if (!validChars.includes(id.at(i))) { + return false; + } + } + return true; + } - public static isPasswordStrongOrThrowError(password: string): boolean { - if (process.env.NODE_ENV === 'test') { - return true; - } - const result = validator.isStrongPassword(password, { - minLength: 8, - minLowercase: 1, - minUppercase: 1, - minNumbers: 1, - minSymbols: 0, - returnScore: false, - pointsPerUnique: undefined, - pointsPerRepeat: undefined, - pointsForContainingLower: undefined, - pointsForContainingUpper: undefined, - pointsForContainingNumber: undefined, - pointsForContainingSymbol: undefined, - }); - if (!result) { - throw new HttpException( - { - message: Messages.PASSWORD_WEAK, - }, - HttpStatus.BAD_REQUEST, - ); - } - return result; - } + public static isPasswordStrongOrThrowError(password: string): boolean { + if (process.env.NODE_ENV === 'test') { + return true; + } + const result = validator.isStrongPassword(password, { + minLength: 8, + minLowercase: 1, + minUppercase: 1, + minNumbers: 1, + minSymbols: 0, + returnScore: false, + pointsPerUnique: undefined, + pointsPerRepeat: undefined, + pointsForContainingLower: undefined, + pointsForContainingUpper: undefined, + pointsForContainingNumber: undefined, + pointsForContainingSymbol: undefined, + }); + if (!result) { + throw new HttpException( + { + message: Messages.PASSWORD_WEAK, + }, + HttpStatus.BAD_REQUEST, + ); + } + return result; + } } diff --git a/backend/src/interceptors/sentry.interceptor.ts b/backend/src/interceptors/sentry.interceptor.ts index 9570fac85..0895d6cf0 100644 --- a/backend/src/interceptors/sentry.interceptor.ts +++ b/backend/src/interceptors/sentry.interceptor.ts @@ -1,35 +1,35 @@ import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common'; +import Sentry from '@sentry/minimal'; import { Observable } from 'rxjs'; import { tap } from 'rxjs/operators'; -import Sentry from '@sentry/minimal'; @Injectable() export class SentryInterceptor implements NestInterceptor { - async intercept(context: ExecutionContext, next: CallHandler): Promise> { - try { - const contextArgs = context.getArgs(); - const userEmail = contextArgs[0]?.decoded?.email; - const receivedConnectionHost = contextArgs[0]?.body?.host; - return next.handle().pipe( - tap(null, async (exception) => { - Sentry.setContext('user_email', { - email: userEmail ? userEmail : 'unknown', - }); - if (receivedConnectionHost) { - Sentry.setContext('received_connection_hostname', { - hostname: receivedConnectionHost, - }); - } - if (exception.originalMessage) { - Sentry.setContext('original_exception_message', { - originalMessage: exception.originalMessage, - }); - } - Sentry.captureException(exception); - }), - ); - } catch (e) { - console.error(e); - } - } + async intercept(context: ExecutionContext, next: CallHandler): Promise> { + try { + const contextArgs = context.getArgs(); + const userEmail = contextArgs[0]?.decoded?.email; + const receivedConnectionHost = contextArgs[0]?.body?.host; + return next.handle().pipe( + tap(null, async (exception) => { + Sentry.setContext('user_email', { + email: userEmail ? userEmail : 'unknown', + }); + if (receivedConnectionHost) { + Sentry.setContext('received_connection_hostname', { + hostname: receivedConnectionHost, + }); + } + if (exception.originalMessage) { + Sentry.setContext('original_exception_message', { + originalMessage: exception.originalMessage, + }); + } + Sentry.captureException(exception); + }), + ); + } catch (e) { + console.error(e); + } + } } diff --git a/backend/src/microservices/gateways/saas-gateway.ts/base-saas-gateway.service.ts b/backend/src/microservices/gateways/saas-gateway.ts/base-saas-gateway.service.ts index a8259b9c8..ef842fe44 100644 --- a/backend/src/microservices/gateways/saas-gateway.ts/base-saas-gateway.service.ts +++ b/backend/src/microservices/gateways/saas-gateway.ts/base-saas-gateway.service.ts @@ -1,57 +1,57 @@ import { Injectable } from '@nestjs/common'; import * as Sentry from '@sentry/node'; -import { generateSaaSJwt } from './utils/generate-saas-jwt.js'; import { isSaaS } from '../../../helpers/app/is-saas.js'; +import { generateSaaSJwt } from './utils/generate-saas-jwt.js'; export type SaaSRequestMethod = 'GET' | 'POST' | 'PUT' | 'DELETE'; export type SaaSResponse = { - status: number; - body: Record; + status: number; + body: Record; }; @Injectable() export class BaseSaasGatewayService { - private readonly baseSaaSUrl = process.env.SAAS_URL || 'http://rocketadmin-private-microservice:3001'; + private readonly baseSaaSUrl = process.env.SAAS_URL || 'http://rocketadmin-private-microservice:3001'; - async sendRequestToSaaS( - patch: string, - method: SaaSRequestMethod, - body: Record, - ): Promise { - try { - if (!isSaaS()) { - return null; - } - const bodyValue = body && method !== 'GET' ? JSON.stringify(body) : undefined; + async sendRequestToSaaS( + patch: string, + method: SaaSRequestMethod, + body: Record, + ): Promise { + try { + if (!isSaaS()) { + return null; + } + const bodyValue = body && method !== 'GET' ? JSON.stringify(body) : undefined; - const jwtToken = generateSaaSJwt(); - const res = await fetch(`${this.baseSaaSUrl}${patch}`, { - method: method, - body: bodyValue, - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${jwtToken}`, - }, - }); + const jwtToken = generateSaaSJwt(); + const res = await fetch(`${this.baseSaaSUrl}${patch}`, { + method: method, + body: bodyValue, + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${jwtToken}`, + }, + }); - return { - status: res.status, - body: await this.bodyToJSON(res), - }; - } catch (e) { - Sentry.captureException(e); - throw e; - } - } + return { + status: res.status, + body: await this.bodyToJSON(res), + }; + } catch (e) { + Sentry.captureException(e); + throw e; + } + } - private async bodyToJSON(res: Response): Promise> { - if (!res.body) { - return {}; - } - try { - return await res.json(); - } catch (_error) { - return {}; - } - } + private async bodyToJSON(res: Response): Promise> { + if (!res.body) { + return {}; + } + try { + return await res.json(); + } catch (_error) { + return {}; + } + } } diff --git a/backend/src/microservices/gateways/saas-gateway.ts/data-structures/found-saas-company-info.ds.ts b/backend/src/microservices/gateways/saas-gateway.ts/data-structures/found-saas-company-info.ds.ts index c635caa2b..ba2837b37 100644 --- a/backend/src/microservices/gateways/saas-gateway.ts/data-structures/found-saas-company-info.ds.ts +++ b/backend/src/microservices/gateways/saas-gateway.ts/data-structures/found-saas-company-info.ds.ts @@ -1,10 +1,10 @@ import { SubscriptionLevelEnum } from '../../../../enums/subscription-level.enum.js'; export class FoundSassCompanyInfoDS { - id: string; - createdAt: Date; - updatedAt: Date; - portal_link?: string; - subscriptionLevel?: SubscriptionLevelEnum; - is_payment_method_added?: boolean; + id: string; + createdAt: Date; + updatedAt: Date; + portal_link?: string; + subscriptionLevel?: SubscriptionLevelEnum; + is_payment_method_added?: boolean; } diff --git a/backend/src/microservices/gateways/saas-gateway.ts/saas-company-gateway.service.ts b/backend/src/microservices/gateways/saas-gateway.ts/saas-company-gateway.service.ts index baf18077c..5b125c41a 100644 --- a/backend/src/microservices/gateways/saas-gateway.ts/saas-company-gateway.service.ts +++ b/backend/src/microservices/gateways/saas-gateway.ts/saas-company-gateway.service.ts @@ -8,94 +8,93 @@ import { FoundSassCompanyInfoDS } from './data-structures/found-saas-company-inf @Injectable() export class SaasCompanyGatewayService extends BaseSaasGatewayService { + public async getCompanyInfo(companyId: string): Promise { + const result = await this.sendRequestToSaaS(`/webhook/company/${companyId}/`, 'GET', null); + if (this.isDataFoundSassCompanyInfoDS(result.body)) { + return result.body; + } + return null; + } - public async getCompanyInfo(companyId: string): Promise { - const result = await this.sendRequestToSaaS(`/webhook/company/${companyId}/`, 'GET', null); - if (this.isDataFoundSassCompanyInfoDS(result.body)) { - return result.body; - } - return null; - } + public async deleteCompany(companyId: string): Promise { + const result = await this.sendRequestToSaaS(`/webhook/company/${companyId}/`, 'DELETE', null); + if (result.status > 299) { + throw new HttpException( + { + message: Messages.SAAS_DELETE_COMPANY_FAILED_UNHANDLED_ERROR, + originalMessage: result?.body?.message ? result.body.message : undefined, + }, + result.status, + ); + } + if (!isObjectEmpty(result.body)) { + return { + success: result.body.success as boolean, + }; + } + return null; + } - public async deleteCompany(companyId: string): Promise { - const result = await this.sendRequestToSaaS(`/webhook/company/${companyId}/`, 'DELETE', null); - if (result.status > 299) { - throw new HttpException( - { - message: Messages.SAAS_DELETE_COMPANY_FAILED_UNHANDLED_ERROR, - originalMessage: result?.body?.message ? result.body.message : undefined, - }, - result.status, - ); - } - if (!isObjectEmpty(result.body)) { - return { - success: result.body.success as boolean, - }; - } - return null; - } + public async getCompanyIdByCustomDomain(customCompanyDomain: string): Promise { + const result = await this.sendRequestToSaaS(`/webhook/company/domain/${customCompanyDomain}/`, 'GET', null); + if (result.status > 299) { + throw new HttpException( + { + message: Messages.SAAS_GET_COMPANY_ID_BY_CUSTOM_DOMAIN_FAILED_UNHANDLED_ERROR, + originalMessage: result?.body?.message ? result.body.message : undefined, + }, + result.status, + ); + } + if (!isObjectEmpty(result.body)) { + return result.body.companyId as string; + } + return null; + } - public async getCompanyIdByCustomDomain(customCompanyDomain: string): Promise { - const result = await this.sendRequestToSaaS(`/webhook/company/domain/${customCompanyDomain}/`, 'GET', null); - if (result.status > 299) { - throw new HttpException( - { - message: Messages.SAAS_GET_COMPANY_ID_BY_CUSTOM_DOMAIN_FAILED_UNHANDLED_ERROR, - originalMessage: result?.body?.message ? result.body.message : undefined, - }, - result.status, - ); - } - if (!isObjectEmpty(result.body)) { - return result.body.companyId as string; - } - return null; - } + public async getCompanyCustomDomainById(companyId: string): Promise { + if (!isSaaS()) { + return null; + } + const result = await this.sendRequestToSaaS(`/webhook/company/${companyId}/domain/`, 'GET', null); + if (result.status > 299) { + throw new HttpException( + { + message: Messages.SAAS_GET_COMPANY_CUSTOM_DOMAIN_BY_ID_FAILED_UNHANDLED_ERROR, + originalMessage: result?.body?.message ? result.body.message : undefined, + }, + result.status, + ); + } + if (!isObjectEmpty(result.body)) { + return result.body.customCompanyDomain as string; + } + return null; + } - public async getCompanyCustomDomainById(companyId: string): Promise { - if (!isSaaS()) { - return null; - } - const result = await this.sendRequestToSaaS(`/webhook/company/${companyId}/domain/`, 'GET', null); - if (result.status > 299) { - throw new HttpException( - { - message: Messages.SAAS_GET_COMPANY_CUSTOM_DOMAIN_BY_ID_FAILED_UNHANDLED_ERROR, - originalMessage: result?.body?.message ? result.body.message : undefined, - }, - result.status, - ); - } - if (!isObjectEmpty(result.body)) { - return result.body.customCompanyDomain as string; - } - return null; - } + public async recountUsersInCompanyRequest(companyId: string): Promise { + if (!isSaaS()) { + return null; + } + const result = await this.sendRequestToSaaS(`/webhook/company/${companyId}/recount/`, 'POST', null); + if (result.status > 299) { + throw new HttpException( + { + message: Messages.SAAS_RECOUNT_USERS_IN_COMPANY_FAILED_UNHANDLED_ERROR, + originalMessage: result?.body?.message ? result.body.message : undefined, + }, + result.status, + ); + } + if (!isObjectEmpty(result.body)) { + return { + success: result.body.success as boolean, + }; + } + return null; + } - public async recountUsersInCompanyRequest(companyId: string): Promise { - if (!isSaaS()) { - return null; - } - const result = await this.sendRequestToSaaS(`/webhook/company/${companyId}/recount/`, 'POST', null); - if (result.status > 299) { - throw new HttpException( - { - message: Messages.SAAS_RECOUNT_USERS_IN_COMPANY_FAILED_UNHANDLED_ERROR, - originalMessage: result?.body?.message ? result.body.message : undefined, - }, - result.status, - ); - } - if (!isObjectEmpty(result.body)) { - return { - success: result.body.success as boolean, - }; - } - return null; - } - - private isDataFoundSassCompanyInfoDS(data: unknown): data is FoundSassCompanyInfoDS { - return typeof data === 'object' && data !== null && 'id' in data && 'createdAt' in data && 'updatedAt' in data; - } + private isDataFoundSassCompanyInfoDS(data: unknown): data is FoundSassCompanyInfoDS { + return typeof data === 'object' && data !== null && 'id' in data && 'createdAt' in data && 'updatedAt' in data; + } } diff --git a/backend/src/microservices/gateways/saas-gateway.ts/saas-gateway.module.ts b/backend/src/microservices/gateways/saas-gateway.ts/saas-gateway.module.ts index d67b2a2c3..f5e808232 100644 --- a/backend/src/microservices/gateways/saas-gateway.ts/saas-gateway.module.ts +++ b/backend/src/microservices/gateways/saas-gateway.ts/saas-gateway.module.ts @@ -4,9 +4,9 @@ import { SaasCompanyGatewayService } from './saas-company-gateway.service.js'; @Global() @Module({ - imports: [], - controllers: [], - providers: [BaseSaasGatewayService, SaasCompanyGatewayService], - exports: [BaseSaasGatewayService, SaasCompanyGatewayService], + imports: [], + controllers: [], + providers: [BaseSaasGatewayService, SaasCompanyGatewayService], + exports: [BaseSaasGatewayService, SaasCompanyGatewayService], }) export class SaaSGatewayModule {} diff --git a/backend/src/microservices/gateways/saas-gateway.ts/utils/generate-request-id.ts b/backend/src/microservices/gateways/saas-gateway.ts/utils/generate-request-id.ts index 2d89b719c..2a8e65994 100644 --- a/backend/src/microservices/gateways/saas-gateway.ts/utils/generate-request-id.ts +++ b/backend/src/microservices/gateways/saas-gateway.ts/utils/generate-request-id.ts @@ -1,4 +1,4 @@ import { nanoid } from 'nanoid'; export function generateRequestId(): string { - return nanoid(10); + return nanoid(10); } diff --git a/backend/src/microservices/gateways/saas-gateway.ts/utils/generate-saas-jwt.ts b/backend/src/microservices/gateways/saas-gateway.ts/utils/generate-saas-jwt.ts index e4cda7fc3..7fabd28ac 100644 --- a/backend/src/microservices/gateways/saas-gateway.ts/utils/generate-saas-jwt.ts +++ b/backend/src/microservices/gateways/saas-gateway.ts/utils/generate-saas-jwt.ts @@ -1,17 +1,17 @@ import jwt from 'jsonwebtoken'; -import { generateRequestId } from './generate-request-id.js'; import { getRequiredEnvVariable } from '../../../../helpers/app/get-requeired-env-variable.js'; +import { generateRequestId } from './generate-request-id.js'; export function generateSaaSJwt(): string { - const today = new Date(); - const exp = new Date(today); - exp.setDate(today.getDate() + 60); - const secret = getRequiredEnvVariable('MICROSERVICE_JWT_SECRET'); - const requestId = generateRequestId(); - return jwt.sign( - { - request_id: requestId, - }, - secret, - ); + const today = new Date(); + const exp = new Date(today); + exp.setDate(today.getDate() + 60); + const secret = getRequiredEnvVariable('MICROSERVICE_JWT_SECRET'); + const requestId = generateRequestId(); + return jwt.sign( + { + request_id: requestId, + }, + secret, + ); } diff --git a/backend/src/microservices/saas-microservice/data-structures/common-responce.ds.ts b/backend/src/microservices/saas-microservice/data-structures/common-responce.ds.ts index 8151ef1b2..88594c82d 100644 --- a/backend/src/microservices/saas-microservice/data-structures/common-responce.ds.ts +++ b/backend/src/microservices/saas-microservice/data-structures/common-responce.ds.ts @@ -1,6 +1,6 @@ import { ApiProperty } from '@nestjs/swagger'; export class SuccessResponse { - @ApiProperty() - success: boolean; + @ApiProperty() + success: boolean; } diff --git a/backend/src/microservices/saas-microservice/data-structures/freeze-connections-in-company.ds.ts b/backend/src/microservices/saas-microservice/data-structures/freeze-connections-in-company.ds.ts index 91c080ac9..12de23a41 100644 --- a/backend/src/microservices/saas-microservice/data-structures/freeze-connections-in-company.ds.ts +++ b/backend/src/microservices/saas-microservice/data-structures/freeze-connections-in-company.ds.ts @@ -1,3 +1,3 @@ export class FreezeConnectionsInCompanyDS { - companyIds: Array; + companyIds: Array; } diff --git a/backend/src/microservices/saas-microservice/data-structures/get-user-info.ds.ts b/backend/src/microservices/saas-microservice/data-structures/get-user-info.ds.ts index 165710f5b..6827da869 100644 --- a/backend/src/microservices/saas-microservice/data-structures/get-user-info.ds.ts +++ b/backend/src/microservices/saas-microservice/data-structures/get-user-info.ds.ts @@ -1,4 +1,4 @@ export class GetUserInfoByIdDS { - userId: string; - companyId?: string; + userId: string; + companyId?: string; } diff --git a/backend/src/microservices/saas-microservice/data-structures/get-users-infos-by-email.ds.ts b/backend/src/microservices/saas-microservice/data-structures/get-users-infos-by-email.ds.ts index 139caa735..1dd500a03 100644 --- a/backend/src/microservices/saas-microservice/data-structures/get-users-infos-by-email.ds.ts +++ b/backend/src/microservices/saas-microservice/data-structures/get-users-infos-by-email.ds.ts @@ -1,6 +1,6 @@ import { ExternalRegistrationProviderEnum } from '../../../entities/user/enums/external-registration-provider.enum.js'; export class GetUsersInfosByEmailDS { - userEmail: string; - externalProvider: ExternalRegistrationProviderEnum; + userEmail: string; + externalProvider: ExternalRegistrationProviderEnum; } diff --git a/backend/src/microservices/saas-microservice/data-structures/register-company.ds.ts b/backend/src/microservices/saas-microservice/data-structures/register-company.ds.ts index ac24a8a4d..d21f3d4fb 100644 --- a/backend/src/microservices/saas-microservice/data-structures/register-company.ds.ts +++ b/backend/src/microservices/saas-microservice/data-structures/register-company.ds.ts @@ -1,12 +1,12 @@ import { ApiProperty } from '@nestjs/swagger'; export class RegisterCompanyWebhookDS { - @ApiProperty() - companyId: string; + @ApiProperty() + companyId: string; - @ApiProperty() - registrarUserId: string; + @ApiProperty() + registrarUserId: string; - @ApiProperty() - companyName: string; + @ApiProperty() + companyName: string; } diff --git a/backend/src/microservices/saas-microservice/data-structures/registered-company.ds.ts b/backend/src/microservices/saas-microservice/data-structures/registered-company.ds.ts index 98a1bee1f..e73c91be7 100644 --- a/backend/src/microservices/saas-microservice/data-structures/registered-company.ds.ts +++ b/backend/src/microservices/saas-microservice/data-structures/registered-company.ds.ts @@ -1,9 +1,9 @@ import { ApiProperty } from '@nestjs/swagger'; export class RegisteredCompanyDS { - @ApiProperty() - userId: string; + @ApiProperty() + userId: string; - @ApiProperty() - companyId: string; + @ApiProperty() + companyId: string; } diff --git a/backend/src/microservices/saas-microservice/data-structures/saas-register-user-with-github.ts b/backend/src/microservices/saas-microservice/data-structures/saas-register-user-with-github.ts index 968d793b6..5ded23810 100644 --- a/backend/src/microservices/saas-microservice/data-structures/saas-register-user-with-github.ts +++ b/backend/src/microservices/saas-microservice/data-structures/saas-register-user-with-github.ts @@ -1,21 +1,21 @@ import { ApiProperty } from '@nestjs/swagger'; export class SaasRegisterUserWithGithub { - @ApiProperty() - email: string; + @ApiProperty() + email: string; - @ApiProperty() - name: string; + @ApiProperty() + name: string; - @ApiProperty() - githubId: number; + @ApiProperty() + githubId: number; - @ApiProperty() - glidCookieValue: string; + @ApiProperty() + glidCookieValue: string; - @ApiProperty({ required: false }) - ipAddress?: string; + @ApiProperty({ required: false }) + ipAddress?: string; - @ApiProperty({ required: false }) - userAgent?: string; + @ApiProperty({ required: false }) + userAgent?: string; } diff --git a/backend/src/microservices/saas-microservice/data-structures/saas-saml-user-register.ds.ts b/backend/src/microservices/saas-microservice/data-structures/saas-saml-user-register.ds.ts index 9cf6e6652..d72b7feb9 100644 --- a/backend/src/microservices/saas-microservice/data-structures/saas-saml-user-register.ds.ts +++ b/backend/src/microservices/saas-microservice/data-structures/saas-saml-user-register.ds.ts @@ -1,21 +1,21 @@ import { ApiProperty } from '@nestjs/swagger'; export class SaasSAMLUserRegisterDS { - @ApiProperty() - email: string; + @ApiProperty() + email: string; - @ApiProperty() - name: string; + @ApiProperty() + name: string; - @ApiProperty() - companyId: string; + @ApiProperty() + companyId: string; - @ApiProperty() - samlConfigId: string; + @ApiProperty() + samlConfigId: string; - @ApiProperty() - samlNameId: string; + @ApiProperty() + samlNameId: string; - @ApiProperty({ required: false }) - samlAttributes?: Record; + @ApiProperty({ required: false }) + samlAttributes?: Record; } diff --git a/backend/src/microservices/saas-microservice/data-structures/sass-register-user-with-google.ts b/backend/src/microservices/saas-microservice/data-structures/sass-register-user-with-google.ts index ee005451d..85b50a65f 100644 --- a/backend/src/microservices/saas-microservice/data-structures/sass-register-user-with-google.ts +++ b/backend/src/microservices/saas-microservice/data-structures/sass-register-user-with-google.ts @@ -1,18 +1,18 @@ import { ApiProperty } from '@nestjs/swagger'; export class SaasRegisterUserWithGoogleDS { - @ApiProperty() - email: string; + @ApiProperty() + email: string; - @ApiProperty() - name: string; + @ApiProperty() + name: string; - @ApiProperty() - glidCookieValue: string; + @ApiProperty() + glidCookieValue: string; - @ApiProperty({ required: false }) - ipAddress?: string; + @ApiProperty({ required: false }) + ipAddress?: string; - @ApiProperty({ required: false }) - userAgent?: string; + @ApiProperty({ required: false }) + userAgent?: string; } diff --git a/backend/src/microservices/saas-microservice/data-structures/suspend-users.ds.ts b/backend/src/microservices/saas-microservice/data-structures/suspend-users.ds.ts index 128ca8e0e..f4281880b 100644 --- a/backend/src/microservices/saas-microservice/data-structures/suspend-users.ds.ts +++ b/backend/src/microservices/saas-microservice/data-structures/suspend-users.ds.ts @@ -1,4 +1,4 @@ export class SuspendUsersDS { - emailsToSuspend: Array; - companyId: string -} \ No newline at end of file + emailsToSuspend: Array; + companyId: string; +} diff --git a/backend/src/microservices/saas-microservice/saas.controller.ts b/backend/src/microservices/saas-microservice/saas.controller.ts index ffd73cf22..22f4ef1bc 100644 --- a/backend/src/microservices/saas-microservice/saas.controller.ts +++ b/backend/src/microservices/saas-microservice/saas.controller.ts @@ -12,13 +12,16 @@ import { UseInterceptors, } from '@nestjs/common'; import { ApiBearerAuth, ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; +import { SkipThrottle } from '@nestjs/throttler'; import { UseCaseType } from '../../common/data-injection.tokens.js'; +import { Timeout } from '../../decorators/timeout.decorator.js'; import { CompanyInfoEntity } from '../../entities/company-info/company-info.entity.js'; import { SaasUsualUserRegisterDS } from '../../entities/user/application/data-structures/usual-register-user.ds.js'; import { FoundUserDto } from '../../entities/user/dto/found-user.dto.js'; import { ExternalRegistrationProviderEnum } from '../../entities/user/enums/external-registration-provider.enum.js'; import { UserEntity } from '../../entities/user/user.entity.js'; import { InTransactionEnum } from '../../enums/in-transaction.enum.js'; +import { Messages } from '../../exceptions/text/messages.js'; import { SentryInterceptor } from '../../interceptors/sentry.interceptor.js'; import { SuccessResponse } from './data-structures/common-responce.ds.js'; import { RegisterCompanyWebhookDS } from './data-structures/register-company.ds.js'; @@ -32,18 +35,15 @@ import { IGetUserInfo, ILoginUserWithGitHub, ILoginUserWithGoogle, - ISaasDemoRegisterUser, ISaaSGetCompanyInfoByUserId, ISaaSGetUsersCountInCompany, + ISaasDemoRegisterUser, ISaasGetUsersInfosByEmail, ISaasRegisterUser, ISaasSAMLRegisterUser, ISuspendUsers, ISuspendUsersOverLimit, } from './use-cases/saas-use-cases.interface.js'; -import { SkipThrottle } from '@nestjs/throttler'; -import { Messages } from '../../exceptions/text/messages.js'; -import { Timeout } from '../../decorators/timeout.decorator.js'; @UseInterceptors(SentryInterceptor) @SkipThrottle() diff --git a/backend/src/microservices/saas-microservice/saas.module.ts b/backend/src/microservices/saas-microservice/saas.module.ts index 117c75bae..65f2a9ecb 100644 --- a/backend/src/microservices/saas-microservice/saas.module.ts +++ b/backend/src/microservices/saas-microservice/saas.module.ts @@ -3,6 +3,9 @@ import { TypeOrmModule } from '@nestjs/typeorm'; import { SaaSAuthMiddleware } from '../../authorization/saas-auth.middleware.js'; import { GlobalDatabaseContext } from '../../common/application/global-database-context.js'; import { BaseType, UseCaseType } from '../../common/data-injection.tokens.js'; +import { UserEntity } from '../../entities/user/user.entity.js'; +import { SignInAuditEntity } from '../../entities/user-sign-in-audit/sign-in-audit.entity.js'; +import { SignInAuditService } from '../../entities/user-sign-in-audit/sign-in-audit.service.js'; import { SaasController } from './saas.controller.js'; import { FreezeConnectionsInCompanyUseCase } from './use-cases/freeze-connections-in-company.use.case.js'; import { GetFullCompanyInfoByUserIdUseCase } from './use-cases/get-full-company-info-by-user-id.use.case.js'; @@ -12,102 +15,99 @@ import { GetUsersInfosByEmailUseCase } from './use-cases/get-users-infos-by-emai import { LoginUserWithGithubUseCase } from './use-cases/login-with-github.use.case.js'; import { LoginWithGoogleUseCase } from './use-cases/login-with-google.use.case.js'; import { RegisteredCompanyWebhookUseCase } from './use-cases/register-company-webhook.use.case.js'; -import { SaasUsualRegisterUseCase } from './use-cases/saas-usual-register-user.use.case.js'; -import { SuspendUsersUseCase } from './use-cases/suspend-users.use.case.js'; -import { UnFreezeConnectionsInCompanyUseCase } from './use-cases/unfreeze-connections-in-company-use.case.js'; import { SaasRegisterDemoUserAccountUseCase } from './use-cases/register-demo-user-account.use.case.js'; import { SaaSRegisterUserWIthSamlUseCase } from './use-cases/register-user-with-saml-use.case.js'; +import { SaasUsualRegisterUseCase } from './use-cases/saas-usual-register-user.use.case.js'; +import { SuspendUsersUseCase } from './use-cases/suspend-users.use.case.js'; import { SuspendUsersOverLimitUseCase } from './use-cases/suspend-users-over-limit.use.case.js'; -import { SignInAuditEntity } from '../../entities/user-sign-in-audit/sign-in-audit.entity.js'; -import { SignInAuditService } from '../../entities/user-sign-in-audit/sign-in-audit.service.js'; -import { UserEntity } from '../../entities/user/user.entity.js'; +import { UnFreezeConnectionsInCompanyUseCase } from './use-cases/unfreeze-connections-in-company-use.case.js'; @Module({ - imports: [TypeOrmModule.forFeature([SignInAuditEntity, UserEntity])], - providers: [ - { - provide: BaseType.GLOBAL_DB_CONTEXT, - useClass: GlobalDatabaseContext, - }, - { - provide: UseCaseType.SAAS_COMPANY_REGISTRATION, - useClass: RegisteredCompanyWebhookUseCase, - }, - { - provide: UseCaseType.SAAS_GET_USER_INFO, - useClass: GetUserInfoUseCase, - }, - { - provide: UseCaseType.SAAS_USUAL_REGISTER_USER, - useClass: SaasUsualRegisterUseCase, - }, - { - provide: UseCaseType.SAAS_LOGIN_USER_WITH_GOOGLE, - useClass: LoginWithGoogleUseCase, - }, - { - provide: UseCaseType.SAAS_LOGIN_USER_WITH_GITHUB, - useClass: LoginUserWithGithubUseCase, - }, - { - provide: UseCaseType.SAAS_SAAS_GET_USERS_INFOS_BY_EMAIL, - useClass: GetUsersInfosByEmailUseCase, - }, - { - provide: UseCaseType.SAAS_SUSPEND_USERS, - useClass: SuspendUsersUseCase, - }, - { - provide: UseCaseType.SAAS_GET_COMPANY_INFO_BY_USER_ID, - useClass: GetFullCompanyInfoByUserIdUseCase, - }, - { - provide: UseCaseType.SAAS_GET_USERS_COUNT_IN_COMPANY, - useClass: GetUsersCountInCompanyByIdUseCase, - }, - { - provide: UseCaseType.FREEZE_CONNECTIONS_IN_COMPANY, - useClass: FreezeConnectionsInCompanyUseCase, - }, - { - provide: UseCaseType.UNFREEZE_CONNECTIONS_IN_COMPANY, - useClass: UnFreezeConnectionsInCompanyUseCase, - }, - { - provide: UseCaseType.SAAS_DEMO_USER_REGISTRATION, - useClass: SaasRegisterDemoUserAccountUseCase, - }, - { - provide: UseCaseType.SAAS_REGISTER_USER_WITH_SAML, - useClass: SaaSRegisterUserWIthSamlUseCase, - }, - { - provide: UseCaseType.SAAS_SUSPEND_USERS_OVER_LIMIT, - useClass: SuspendUsersOverLimitUseCase, - }, - SignInAuditService, - ], - controllers: [SaasController], - exports: [], + imports: [TypeOrmModule.forFeature([SignInAuditEntity, UserEntity])], + providers: [ + { + provide: BaseType.GLOBAL_DB_CONTEXT, + useClass: GlobalDatabaseContext, + }, + { + provide: UseCaseType.SAAS_COMPANY_REGISTRATION, + useClass: RegisteredCompanyWebhookUseCase, + }, + { + provide: UseCaseType.SAAS_GET_USER_INFO, + useClass: GetUserInfoUseCase, + }, + { + provide: UseCaseType.SAAS_USUAL_REGISTER_USER, + useClass: SaasUsualRegisterUseCase, + }, + { + provide: UseCaseType.SAAS_LOGIN_USER_WITH_GOOGLE, + useClass: LoginWithGoogleUseCase, + }, + { + provide: UseCaseType.SAAS_LOGIN_USER_WITH_GITHUB, + useClass: LoginUserWithGithubUseCase, + }, + { + provide: UseCaseType.SAAS_SAAS_GET_USERS_INFOS_BY_EMAIL, + useClass: GetUsersInfosByEmailUseCase, + }, + { + provide: UseCaseType.SAAS_SUSPEND_USERS, + useClass: SuspendUsersUseCase, + }, + { + provide: UseCaseType.SAAS_GET_COMPANY_INFO_BY_USER_ID, + useClass: GetFullCompanyInfoByUserIdUseCase, + }, + { + provide: UseCaseType.SAAS_GET_USERS_COUNT_IN_COMPANY, + useClass: GetUsersCountInCompanyByIdUseCase, + }, + { + provide: UseCaseType.FREEZE_CONNECTIONS_IN_COMPANY, + useClass: FreezeConnectionsInCompanyUseCase, + }, + { + provide: UseCaseType.UNFREEZE_CONNECTIONS_IN_COMPANY, + useClass: UnFreezeConnectionsInCompanyUseCase, + }, + { + provide: UseCaseType.SAAS_DEMO_USER_REGISTRATION, + useClass: SaasRegisterDemoUserAccountUseCase, + }, + { + provide: UseCaseType.SAAS_REGISTER_USER_WITH_SAML, + useClass: SaaSRegisterUserWIthSamlUseCase, + }, + { + provide: UseCaseType.SAAS_SUSPEND_USERS_OVER_LIMIT, + useClass: SuspendUsersOverLimitUseCase, + }, + SignInAuditService, + ], + controllers: [SaasController], + exports: [], }) export class SaasModule { - public configure(consumer: MiddlewareConsumer): void { - consumer - .apply(SaaSAuthMiddleware) - .forRoutes( - { path: 'saas/company/registered', method: RequestMethod.POST }, - { path: 'saas/user/:userId', method: RequestMethod.GET }, - { path: 'saas/user/register', method: RequestMethod.POST }, - { path: 'saas/user/demo/register', method: RequestMethod.POST }, - { path: 'saas/user/google/login', method: RequestMethod.POST }, - { path: 'saas/user/github/login', method: RequestMethod.POST }, - { path: 'saas/company/:companyId/users/suspend', method: RequestMethod.PUT }, - { path: 'saas/company/:companyId/users/suspend-above-limit', method: RequestMethod.PUT }, - { path: 'saas/user/:userId/company', method: RequestMethod.GET }, - { path: 'saas/company/:companyId/users/count', method: RequestMethod.GET }, - { path: 'saas/company/freeze-connections', method: RequestMethod.PUT }, - { path: 'saas/company/unfreeze-connections', method: RequestMethod.PUT }, - { path: 'saas/user/saml/login', method: RequestMethod.POST }, - ); - } + public configure(consumer: MiddlewareConsumer): void { + consumer + .apply(SaaSAuthMiddleware) + .forRoutes( + { path: 'saas/company/registered', method: RequestMethod.POST }, + { path: 'saas/user/:userId', method: RequestMethod.GET }, + { path: 'saas/user/register', method: RequestMethod.POST }, + { path: 'saas/user/demo/register', method: RequestMethod.POST }, + { path: 'saas/user/google/login', method: RequestMethod.POST }, + { path: 'saas/user/github/login', method: RequestMethod.POST }, + { path: 'saas/company/:companyId/users/suspend', method: RequestMethod.PUT }, + { path: 'saas/company/:companyId/users/suspend-above-limit', method: RequestMethod.PUT }, + { path: 'saas/user/:userId/company', method: RequestMethod.GET }, + { path: 'saas/company/:companyId/users/count', method: RequestMethod.GET }, + { path: 'saas/company/freeze-connections', method: RequestMethod.PUT }, + { path: 'saas/company/unfreeze-connections', method: RequestMethod.PUT }, + { path: 'saas/user/saml/login', method: RequestMethod.POST }, + ); + } } diff --git a/backend/src/microservices/saas-microservice/use-cases/freeze-connections-in-company.use.case.ts b/backend/src/microservices/saas-microservice/use-cases/freeze-connections-in-company.use.case.ts index a350a8faf..1c883f7c4 100644 --- a/backend/src/microservices/saas-microservice/use-cases/freeze-connections-in-company.use.case.ts +++ b/backend/src/microservices/saas-microservice/use-cases/freeze-connections-in-company.use.case.ts @@ -1,29 +1,29 @@ import { Inject, Injectable, Scope } from '@nestjs/common'; +import AbstractUseCase from '../../../common/abstract-use.case.js'; +import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; +import { BaseType } from '../../../common/data-injection.tokens.js'; import { SuccessResponse } from '../data-structures/common-responce.ds.js'; import { FreezeConnectionsInCompanyDS } from '../data-structures/freeze-connections-in-company.ds.js'; import { IFreezeConnectionsInCompany } from './saas-use-cases.interface.js'; -import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; -import { BaseType } from '../../../common/data-injection.tokens.js'; -import AbstractUseCase from '../../../common/abstract-use.case.js'; @Injectable({ scope: Scope.REQUEST }) export class FreezeConnectionsInCompanyUseCase - extends AbstractUseCase - implements IFreezeConnectionsInCompany + extends AbstractUseCase + implements IFreezeConnectionsInCompany { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(_inputData: FreezeConnectionsInCompanyDS): Promise { - return { success: true }; - // const { companyIds } = inputData; - // const companyPaidConnections = await this._dbContext.companyInfoRepository.findCompaniesPaidConnections(companyIds); - // const connectionsIds = companyPaidConnections.map((connection) => connection.id); - // await this._dbContext.connectionRepository.freezeConnections(connectionsIds); - // return { success: true }; - } + protected async implementation(_inputData: FreezeConnectionsInCompanyDS): Promise { + return { success: true }; + // const { companyIds } = inputData; + // const companyPaidConnections = await this._dbContext.companyInfoRepository.findCompaniesPaidConnections(companyIds); + // const connectionsIds = companyPaidConnections.map((connection) => connection.id); + // await this._dbContext.connectionRepository.freezeConnections(connectionsIds); + // return { success: true }; + } } diff --git a/backend/src/microservices/saas-microservice/use-cases/get-full-company-info-by-user-id.use.case.ts b/backend/src/microservices/saas-microservice/use-cases/get-full-company-info-by-user-id.use.case.ts index bc426e790..f55828d2e 100644 --- a/backend/src/microservices/saas-microservice/use-cases/get-full-company-info-by-user-id.use.case.ts +++ b/backend/src/microservices/saas-microservice/use-cases/get-full-company-info-by-user-id.use.case.ts @@ -1,28 +1,28 @@ import { Inject, Injectable, NotFoundException, Scope } from '@nestjs/common'; -import { BaseType } from '../../../common/data-injection.tokens.js'; -import { CompanyInfoEntity } from '../../../entities/company-info/company-info.entity.js'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; -import { ISaaSGetCompanyInfoByUserId } from './saas-use-cases.interface.js'; +import { BaseType } from '../../../common/data-injection.tokens.js'; +import { CompanyInfoEntity } from '../../../entities/company-info/company-info.entity.js'; import { Messages } from '../../../exceptions/text/messages.js'; +import { ISaaSGetCompanyInfoByUserId } from './saas-use-cases.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class GetFullCompanyInfoByUserIdUseCase - extends AbstractUseCase - implements ISaaSGetCompanyInfoByUserId + extends AbstractUseCase + implements ISaaSGetCompanyInfoByUserId { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(userId: string): Promise { - const foundCompany = await this._dbContext.companyInfoRepository.findFullCompanyInfoByUserId(userId); - if (!foundCompany) { - throw new NotFoundException(Messages.COMPANY_NOT_FOUND); - } - return foundCompany; - } + protected async implementation(userId: string): Promise { + const foundCompany = await this._dbContext.companyInfoRepository.findFullCompanyInfoByUserId(userId); + if (!foundCompany) { + throw new NotFoundException(Messages.COMPANY_NOT_FOUND); + } + return foundCompany; + } } diff --git a/backend/src/microservices/saas-microservice/use-cases/get-user-info.use.case.ts b/backend/src/microservices/saas-microservice/use-cases/get-user-info.use.case.ts index ad2479d0d..00f9b7a35 100644 --- a/backend/src/microservices/saas-microservice/use-cases/get-user-info.use.case.ts +++ b/backend/src/microservices/saas-microservice/use-cases/get-user-info.use.case.ts @@ -9,30 +9,30 @@ import { IGetUserInfo } from './saas-use-cases.interface.js'; @Injectable() export class GetUserInfoUseCase extends AbstractUseCase implements IGetUserInfo { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: GetUserInfoByIdDS): Promise { - const { userId, companyId } = inputData; - let foundUser: UserEntity; - if (companyId) { - foundUser = await this._dbContext.userRepository.findOneUserByIdAndCompanyId(userId, companyId); - } else { - foundUser = await this._dbContext.userRepository.findOneUserById(userId); - } - delete foundUser.password; - if (!foundUser) { - throw new HttpException( - { - message: Messages.USER_NOT_FOUND, - }, - HttpStatus.BAD_REQUEST, - ); - } - return foundUser; - } + protected async implementation(inputData: GetUserInfoByIdDS): Promise { + const { userId, companyId } = inputData; + let foundUser: UserEntity; + if (companyId) { + foundUser = await this._dbContext.userRepository.findOneUserByIdAndCompanyId(userId, companyId); + } else { + foundUser = await this._dbContext.userRepository.findOneUserById(userId); + } + delete foundUser.password; + if (!foundUser) { + throw new HttpException( + { + message: Messages.USER_NOT_FOUND, + }, + HttpStatus.BAD_REQUEST, + ); + } + return foundUser; + } } diff --git a/backend/src/microservices/saas-microservice/use-cases/get-users-count-in-company.use.case.ts b/backend/src/microservices/saas-microservice/use-cases/get-users-count-in-company.use.case.ts index d4374c45b..aaebdb114 100644 --- a/backend/src/microservices/saas-microservice/use-cases/get-users-count-in-company.use.case.ts +++ b/backend/src/microservices/saas-microservice/use-cases/get-users-count-in-company.use.case.ts @@ -1,29 +1,29 @@ import { Inject, Injectable } from '@nestjs/common'; +import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import AbstractUseCase from '../../../common/abstract-use.case.js'; import { ISaaSGetUsersCountInCompany } from './saas-use-cases.interface.js'; @Injectable() export class GetUsersCountInCompanyByIdUseCase - extends AbstractUseCase - implements ISaaSGetUsersCountInCompany + extends AbstractUseCase + implements ISaaSGetUsersCountInCompany { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - public async implementation(companyId: string): Promise { - const usersCount = await this._dbContext.userRepository.count({ - where: { - company: { - id: companyId, - }, - }, - }); - return usersCount; - } + public async implementation(companyId: string): Promise { + const usersCount = await this._dbContext.userRepository.count({ + where: { + company: { + id: companyId, + }, + }, + }); + return usersCount; + } } diff --git a/backend/src/microservices/saas-microservice/use-cases/get-users-infos-by-email.use.case.ts b/backend/src/microservices/saas-microservice/use-cases/get-users-infos-by-email.use.case.ts index a260ab20e..4838b3bd9 100644 --- a/backend/src/microservices/saas-microservice/use-cases/get-users-infos-by-email.use.case.ts +++ b/backend/src/microservices/saas-microservice/use-cases/get-users-infos-by-email.use.case.ts @@ -3,30 +3,30 @@ import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; import { UserEntity } from '../../../entities/user/user.entity.js'; -import { ISaasGetUsersInfosByEmail } from './saas-use-cases.interface.js'; import { GetUsersInfosByEmailDS } from '../data-structures/get-users-infos-by-email.ds.js'; +import { ISaasGetUsersInfosByEmail } from './saas-use-cases.interface.js'; export class GetUsersInfosByEmailUseCase - extends AbstractUseCase> - implements ISaasGetUsersInfosByEmail + extends AbstractUseCase> + implements ISaasGetUsersInfosByEmail { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(usersData: GetUsersInfosByEmailDS): Promise> { - const { userEmail, externalProvider } = usersData; - const foundUsers: Array = await this._dbContext.userRepository.findAllUsersWithEmail( - userEmail, - externalProvider, - ); - return foundUsers.map((user) => { - delete user.password; - delete user.company; - return user; - }); - } + protected async implementation(usersData: GetUsersInfosByEmailDS): Promise> { + const { userEmail, externalProvider } = usersData; + const foundUsers: Array = await this._dbContext.userRepository.findAllUsersWithEmail( + userEmail, + externalProvider, + ); + return foundUsers.map((user) => { + delete user.password; + delete user.company; + return user; + }); + } } diff --git a/backend/src/microservices/saas-microservice/use-cases/login-with-github.use.case.ts b/backend/src/microservices/saas-microservice/use-cases/login-with-github.use.case.ts index 8271026cf..701ebee9a 100644 --- a/backend/src/microservices/saas-microservice/use-cases/login-with-github.use.case.ts +++ b/backend/src/microservices/saas-microservice/use-cases/login-with-github.use.case.ts @@ -8,97 +8,97 @@ import { ExternalRegistrationProviderEnum } from '../../../entities/user/enums/e import { UserRoleEnum } from '../../../entities/user/enums/user-role.enum.js'; import { UserEntity } from '../../../entities/user/user.entity.js'; import { buildUserGitHubIdentifierEntity } from '../../../entities/user/utils/build-github-identifier-entity.js'; +import { SignInMethodEnum } from '../../../entities/user-sign-in-audit/enums/sign-in-method.enum.js'; +import { SignInStatusEnum } from '../../../entities/user-sign-in-audit/enums/sign-in-status.enum.js'; +import { SignInAuditService } from '../../../entities/user-sign-in-audit/sign-in-audit.service.js'; import { Messages } from '../../../exceptions/text/messages.js'; import { SaasRegisterUserWithGithub } from '../data-structures/saas-register-user-with-github.js'; import { ILoginUserWithGitHub } from './saas-use-cases.interface.js'; -import { SignInAuditService } from '../../../entities/user-sign-in-audit/sign-in-audit.service.js'; -import { SignInStatusEnum } from '../../../entities/user-sign-in-audit/enums/sign-in-status.enum.js'; -import { SignInMethodEnum } from '../../../entities/user-sign-in-audit/enums/sign-in-method.enum.js'; @Injectable() export class LoginUserWithGithubUseCase - extends AbstractUseCase - implements ILoginUserWithGitHub + extends AbstractUseCase + implements ILoginUserWithGitHub { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private readonly demoDataService: DemoDataService, - private readonly signInAuditService: SignInAuditService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly demoDataService: DemoDataService, + private readonly signInAuditService: SignInAuditService, + ) { + super(); + } - protected async implementation(inputData: SaasRegisterUserWithGithub): Promise { - const { email, githubId, glidCookieValue, name, ipAddress, userAgent } = inputData; - const foundUser: UserEntity = await this._dbContext.userRepository.findOneUserByGitHubId(githubId); - if (foundUser) { - if (foundUser.name !== name && name) { - foundUser.name = name; - } - if (foundUser.email !== email) { - foundUser.email = email; - } - await this._dbContext.userRepository.saveUserEntity(foundUser); - await this.recordSignInAudit(email, foundUser.id, SignInStatusEnum.SUCCESS, ipAddress, userAgent); - return foundUser; - } - const userData: RegisterUserDs = { - email: email, - gclidValue: glidCookieValue, - password: null, - isActive: true, - name: name ? name : null, - role: UserRoleEnum.ADMIN, - }; + protected async implementation(inputData: SaasRegisterUserWithGithub): Promise { + const { email, githubId, glidCookieValue, name, ipAddress, userAgent } = inputData; + const foundUser: UserEntity = await this._dbContext.userRepository.findOneUserByGitHubId(githubId); + if (foundUser) { + if (foundUser.name !== name && name) { + foundUser.name = name; + } + if (foundUser.email !== email) { + foundUser.email = email; + } + await this._dbContext.userRepository.saveUserEntity(foundUser); + await this.recordSignInAudit(email, foundUser.id, SignInStatusEnum.SUCCESS, ipAddress, userAgent); + return foundUser; + } + const userData: RegisterUserDs = { + email: email, + gclidValue: glidCookieValue, + password: null, + isActive: true, + name: name ? name : null, + role: UserRoleEnum.ADMIN, + }; - try { - const savedUser = await this._dbContext.userRepository.saveRegisteringUser( - userData, - ExternalRegistrationProviderEnum.GITHUB, - ); + try { + const savedUser = await this._dbContext.userRepository.saveRegisteringUser( + userData, + ExternalRegistrationProviderEnum.GITHUB, + ); - const newUserGitHubIdentifier = buildUserGitHubIdentifierEntity(savedUser, Number(githubId)); - await this._dbContext.userGitHubIdentifierRepository.saveGitHubIdentifierEntity(newUserGitHubIdentifier); + const newUserGitHubIdentifier = buildUserGitHubIdentifierEntity(savedUser, Number(githubId)); + await this._dbContext.userGitHubIdentifierRepository.saveGitHubIdentifierEntity(newUserGitHubIdentifier); - await this.demoDataService.createDemoDataForUser(savedUser.id); + await this.demoDataService.createDemoDataForUser(savedUser.id); - await this.recordSignInAudit(email, savedUser.id, SignInStatusEnum.SUCCESS, ipAddress, userAgent); + await this.recordSignInAudit(email, savedUser.id, SignInStatusEnum.SUCCESS, ipAddress, userAgent); - return savedUser; - } catch (_e) { - await this.recordSignInAudit( - email, - null, - SignInStatusEnum.FAILED, - ipAddress, - userAgent, - Messages.GITHUB_REGISTRATION_FAILED, - ); - throw new InternalServerErrorException(Messages.GITHUB_REGISTRATION_FAILED); - } - } + return savedUser; + } catch (_e) { + await this.recordSignInAudit( + email, + null, + SignInStatusEnum.FAILED, + ipAddress, + userAgent, + Messages.GITHUB_REGISTRATION_FAILED, + ); + throw new InternalServerErrorException(Messages.GITHUB_REGISTRATION_FAILED); + } + } - private async recordSignInAudit( - email: string, - userId: string | null, - status: SignInStatusEnum, - ipAddress: string, - userAgent: string, - failureReason?: string, - ): Promise { - try { - await this.signInAuditService.createSignInAuditRecord({ - email, - userId, - status, - signInMethod: SignInMethodEnum.GITHUB, - ipAddress, - userAgent, - failureReason, - }); - } catch (e) { - console.error('Failed to record sign-in audit:', e); - } - } + private async recordSignInAudit( + email: string, + userId: string | null, + status: SignInStatusEnum, + ipAddress: string, + userAgent: string, + failureReason?: string, + ): Promise { + try { + await this.signInAuditService.createSignInAuditRecord({ + email, + userId, + status, + signInMethod: SignInMethodEnum.GITHUB, + ipAddress, + userAgent, + failureReason, + }); + } catch (e) { + console.error('Failed to record sign-in audit:', e); + } + } } diff --git a/backend/src/microservices/saas-microservice/use-cases/login-with-google.use.case.ts b/backend/src/microservices/saas-microservice/use-cases/login-with-google.use.case.ts index 7249be68c..0efaf4c47 100644 --- a/backend/src/microservices/saas-microservice/use-cases/login-with-google.use.case.ts +++ b/backend/src/microservices/saas-microservice/use-cases/login-with-google.use.case.ts @@ -6,77 +6,77 @@ import { DemoDataService } from '../../../entities/demo-data/demo-data.service.j import { RegisterUserDs } from '../../../entities/user/application/data-structures/register-user-ds.js'; import { ExternalRegistrationProviderEnum } from '../../../entities/user/enums/external-registration-provider.enum.js'; import { UserEntity } from '../../../entities/user/user.entity.js'; +import { SignInMethodEnum } from '../../../entities/user-sign-in-audit/enums/sign-in-method.enum.js'; +import { SignInStatusEnum } from '../../../entities/user-sign-in-audit/enums/sign-in-status.enum.js'; +import { SignInAuditService } from '../../../entities/user-sign-in-audit/sign-in-audit.service.js'; import { SaasRegisterUserWithGoogleDS } from '../data-structures/sass-register-user-with-google.js'; import { ILoginUserWithGoogle } from './saas-use-cases.interface.js'; -import { SignInAuditService } from '../../../entities/user-sign-in-audit/sign-in-audit.service.js'; -import { SignInStatusEnum } from '../../../entities/user-sign-in-audit/enums/sign-in-status.enum.js'; -import { SignInMethodEnum } from '../../../entities/user-sign-in-audit/enums/sign-in-method.enum.js'; @Injectable() export class LoginWithGoogleUseCase - extends AbstractUseCase - implements ILoginUserWithGoogle + extends AbstractUseCase + implements ILoginUserWithGoogle { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private readonly demoDataService: DemoDataService, - private readonly signInAuditService: SignInAuditService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly demoDataService: DemoDataService, + private readonly signInAuditService: SignInAuditService, + ) { + super(); + } - protected async implementation(inputData: SaasRegisterUserWithGoogleDS): Promise { - const { email, name, glidCookieValue, ipAddress, userAgent } = inputData; + protected async implementation(inputData: SaasRegisterUserWithGoogleDS): Promise { + const { email, name, glidCookieValue, ipAddress, userAgent } = inputData; - const foundUser: UserEntity = await this._dbContext.userRepository.findOneUserByEmail( - email, - ExternalRegistrationProviderEnum.GOOGLE, - ); - if (foundUser) { - if (foundUser.name !== name && name) { - foundUser.name = name; - await this._dbContext.userRepository.saveUserEntity(foundUser); - } - await this.recordSignInAudit(email, foundUser.id, SignInStatusEnum.SUCCESS, ipAddress, userAgent); - return foundUser; - } - const userData: RegisterUserDs = { - email: email, - gclidValue: glidCookieValue, - password: null, - isActive: true, - name: name ? name : null, - }; - const savedUser = await this._dbContext.userRepository.saveRegisteringUser( - userData, - ExternalRegistrationProviderEnum.GOOGLE, - ); - await this.demoDataService.createDemoDataForUser(savedUser.id); - await this.recordSignInAudit(email, savedUser.id, SignInStatusEnum.SUCCESS, ipAddress, userAgent); - return savedUser; - } + const foundUser: UserEntity = await this._dbContext.userRepository.findOneUserByEmail( + email, + ExternalRegistrationProviderEnum.GOOGLE, + ); + if (foundUser) { + if (foundUser.name !== name && name) { + foundUser.name = name; + await this._dbContext.userRepository.saveUserEntity(foundUser); + } + await this.recordSignInAudit(email, foundUser.id, SignInStatusEnum.SUCCESS, ipAddress, userAgent); + return foundUser; + } + const userData: RegisterUserDs = { + email: email, + gclidValue: glidCookieValue, + password: null, + isActive: true, + name: name ? name : null, + }; + const savedUser = await this._dbContext.userRepository.saveRegisteringUser( + userData, + ExternalRegistrationProviderEnum.GOOGLE, + ); + await this.demoDataService.createDemoDataForUser(savedUser.id); + await this.recordSignInAudit(email, savedUser.id, SignInStatusEnum.SUCCESS, ipAddress, userAgent); + return savedUser; + } - private async recordSignInAudit( - email: string, - userId: string | null, - status: SignInStatusEnum, - ipAddress: string, - userAgent: string, - failureReason?: string, - ): Promise { - try { - await this.signInAuditService.createSignInAuditRecord({ - email, - userId, - status, - signInMethod: SignInMethodEnum.GOOGLE, - ipAddress, - userAgent, - failureReason, - }); - } catch (e) { - console.error('Failed to record sign-in audit:', e); - } - } + private async recordSignInAudit( + email: string, + userId: string | null, + status: SignInStatusEnum, + ipAddress: string, + userAgent: string, + failureReason?: string, + ): Promise { + try { + await this.signInAuditService.createSignInAuditRecord({ + email, + userId, + status, + signInMethod: SignInMethodEnum.GOOGLE, + ipAddress, + userAgent, + failureReason, + }); + } catch (e) { + console.error('Failed to record sign-in audit:', e); + } + } } diff --git a/backend/src/microservices/saas-microservice/use-cases/register-company-webhook.use.case.ts b/backend/src/microservices/saas-microservice/use-cases/register-company-webhook.use.case.ts index 5be65367d..110ea3892 100644 --- a/backend/src/microservices/saas-microservice/use-cases/register-company-webhook.use.case.ts +++ b/backend/src/microservices/saas-microservice/use-cases/register-company-webhook.use.case.ts @@ -1,73 +1,73 @@ import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common'; +import * as Sentry from '@sentry/node'; import AbstractUseCase from '../../../common/abstract-use.case.js'; -import { RegisterCompanyWebhookDS } from '../data-structures/register-company.ds.js'; -import { RegisteredCompanyDS } from '../data-structures/registered-company.ds.js'; -import { ICompanyRegistration } from './saas-use-cases.interface.js'; -import { BaseType } from '../../../common/data-injection.tokens.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; -import { Messages } from '../../../exceptions/text/messages.js'; +import { BaseType } from '../../../common/data-injection.tokens.js'; import { CompanyInfoEntity } from '../../../entities/company-info/company-info.entity.js'; import { UserRoleEnum } from '../../../entities/user/enums/user-role.enum.js'; -import * as Sentry from '@sentry/node'; +import { Messages } from '../../../exceptions/text/messages.js'; +import { RegisterCompanyWebhookDS } from '../data-structures/register-company.ds.js'; +import { RegisteredCompanyDS } from '../data-structures/registered-company.ds.js'; +import { ICompanyRegistration } from './saas-use-cases.interface.js'; @Injectable() export class RegisteredCompanyWebhookUseCase - extends AbstractUseCase - implements ICompanyRegistration + extends AbstractUseCase + implements ICompanyRegistration { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: RegisterCompanyWebhookDS): Promise { - const { companyId, registrarUserId, companyName } = inputData; - const foundUser = await this._dbContext.userRepository.findOneUserById(registrarUserId); - if (!foundUser) { - throw new HttpException( - { - message: Messages.USER_NOT_FOUND, - }, - HttpStatus.NOT_FOUND, - ); - } - const foundCompanyInfo = await this._dbContext.companyInfoRepository.findCompanyInfoWithUsersById(companyId); - if (foundCompanyInfo) { - throw new HttpException( - { - message: Messages.COMPANY_ALREADY_EXISTS, - }, - HttpStatus.BAD_REQUEST, - ); - } + protected async implementation(inputData: RegisterCompanyWebhookDS): Promise { + const { companyId, registrarUserId, companyName } = inputData; + const foundUser = await this._dbContext.userRepository.findOneUserById(registrarUserId); + if (!foundUser) { + throw new HttpException( + { + message: Messages.USER_NOT_FOUND, + }, + HttpStatus.NOT_FOUND, + ); + } + const foundCompanyInfo = await this._dbContext.companyInfoRepository.findCompanyInfoWithUsersById(companyId); + if (foundCompanyInfo) { + throw new HttpException( + { + message: Messages.COMPANY_ALREADY_EXISTS, + }, + HttpStatus.BAD_REQUEST, + ); + } - const newCompanyInfo = new CompanyInfoEntity(); - newCompanyInfo.name = companyName ? companyName : 'New Company'; - newCompanyInfo.id = companyId; - newCompanyInfo.show_test_connections = true; - const savedCompanyInfo = await this._dbContext.companyInfoRepository.save(newCompanyInfo); - foundUser.company = savedCompanyInfo; - foundUser.role = UserRoleEnum.ADMIN; - const savedUser = await this._dbContext.userRepository.saveUserEntity(foundUser); + const newCompanyInfo = new CompanyInfoEntity(); + newCompanyInfo.name = companyName ? companyName : 'New Company'; + newCompanyInfo.id = companyId; + newCompanyInfo.show_test_connections = true; + const savedCompanyInfo = await this._dbContext.companyInfoRepository.save(newCompanyInfo); + foundUser.company = savedCompanyInfo; + foundUser.role = UserRoleEnum.ADMIN; + const savedUser = await this._dbContext.userRepository.saveUserEntity(foundUser); - try { - const userTestConnectionsWithoutCompany = - await this._dbContext.connectionRepository.foundUserTestConnectionsWithoutCompany(registrarUserId); - if (userTestConnectionsWithoutCompany.length) { - userTestConnectionsWithoutCompany.forEach((connection) => { - connection.company = savedCompanyInfo; - }); - await this._dbContext.connectionRepository.save(userTestConnectionsWithoutCompany); - } - } catch (error) { - Sentry.captureException(error); - } + try { + const userTestConnectionsWithoutCompany = + await this._dbContext.connectionRepository.foundUserTestConnectionsWithoutCompany(registrarUserId); + if (userTestConnectionsWithoutCompany.length) { + userTestConnectionsWithoutCompany.forEach((connection) => { + connection.company = savedCompanyInfo; + }); + await this._dbContext.connectionRepository.save(userTestConnectionsWithoutCompany); + } + } catch (error) { + Sentry.captureException(error); + } - return { - userId: savedUser.id, - companyId: savedCompanyInfo.id, - }; - } + return { + userId: savedUser.id, + companyId: savedCompanyInfo.id, + }; + } } diff --git a/backend/src/microservices/saas-microservice/use-cases/register-demo-user-account.use.case.ts b/backend/src/microservices/saas-microservice/use-cases/register-demo-user-account.use.case.ts index b9e1593e1..b68c5e6e6 100644 --- a/backend/src/microservices/saas-microservice/use-cases/register-demo-user-account.use.case.ts +++ b/backend/src/microservices/saas-microservice/use-cases/register-demo-user-account.use.case.ts @@ -13,71 +13,71 @@ import { ISaasDemoRegisterUser } from './saas-use-cases.interface.js'; @Injectable() export class SaasRegisterDemoUserAccountUseCase - extends AbstractUseCase - implements ISaasDemoRegisterUser + extends AbstractUseCase + implements ISaasDemoRegisterUser { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - private readonly demoDataService: DemoDataService, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + private readonly demoDataService: DemoDataService, + ) { + super(); + } - protected async implementation(userData: SaaSRegisterDemoUserAccountDS): Promise { - const savedUser = await this.createDemoUser(userData); + protected async implementation(userData: SaaSRegisterDemoUserAccountDS): Promise { + const savedUser = await this.createDemoUser(userData); - const createdTestConnections = await this.demoDataService.createDemoDataForUser(savedUser.id); + const createdTestConnections = await this.demoDataService.createDemoDataForUser(savedUser.id); - const savedCompanyInfo = await this.createCompanyInfo(userData, createdTestConnections); + const savedCompanyInfo = await this.createCompanyInfo(userData, createdTestConnections); - savedUser.company = savedCompanyInfo; - await this._dbContext.userRepository.saveUserEntity(savedUser); + savedUser.company = savedCompanyInfo; + await this._dbContext.userRepository.saveUserEntity(savedUser); - return this.buildFoundUserDto(savedUser); - } + return this.buildFoundUserDto(savedUser); + } - private async createDemoUser(userData: SaaSRegisterDemoUserAccountDS): Promise { - const { email, gclidValue } = userData; + private async createDemoUser(userData: SaaSRegisterDemoUserAccountDS): Promise { + const { email, gclidValue } = userData; - const demoUser = new UserEntity(); - demoUser.email = email; - demoUser.isDemoAccount = true; - demoUser.gclid = gclidValue; - demoUser.name = 'Demo User'; - demoUser.role = UserRoleEnum.ADMIN; + const demoUser = new UserEntity(); + demoUser.email = email; + demoUser.isDemoAccount = true; + demoUser.gclid = gclidValue; + demoUser.name = 'Demo User'; + demoUser.role = UserRoleEnum.ADMIN; - return await this._dbContext.userRepository.save(demoUser); - } + return await this._dbContext.userRepository.save(demoUser); + } - private async createCompanyInfo( - userData: SaaSRegisterDemoUserAccountDS, - createdTestConnections: ConnectionEntity[], - ): Promise { - const { companyId, companyName } = userData; + private async createCompanyInfo( + userData: SaaSRegisterDemoUserAccountDS, + createdTestConnections: ConnectionEntity[], + ): Promise { + const { companyId, companyName } = userData; - const newCompanyInfo = new CompanyInfoEntity(); - newCompanyInfo.id = companyId; - newCompanyInfo.name = companyName; - newCompanyInfo.show_test_connections = true; - newCompanyInfo.connections = [...createdTestConnections]; + const newCompanyInfo = new CompanyInfoEntity(); + newCompanyInfo.id = companyId; + newCompanyInfo.name = companyName; + newCompanyInfo.show_test_connections = true; + newCompanyInfo.connections = [...createdTestConnections]; - return await this._dbContext.companyInfoRepository.save(newCompanyInfo); - } + return await this._dbContext.companyInfoRepository.save(newCompanyInfo); + } - private buildFoundUserDto(savedUser: UserEntity): FoundUserDto { - return { - id: savedUser.id, - createdAt: savedUser.createdAt, - isActive: savedUser.isActive, - email: savedUser.email, - intercom_hash: null, - name: savedUser.name, - role: savedUser.role, - is_2fa_enabled: false, - suspended: false, - externalRegistrationProvider: savedUser.externalRegistrationProvider, - show_test_connections: savedUser.showTestConnections, - }; - } + private buildFoundUserDto(savedUser: UserEntity): FoundUserDto { + return { + id: savedUser.id, + createdAt: savedUser.createdAt, + isActive: savedUser.isActive, + email: savedUser.email, + intercom_hash: null, + name: savedUser.name, + role: savedUser.role, + is_2fa_enabled: false, + suspended: false, + externalRegistrationProvider: savedUser.externalRegistrationProvider, + show_test_connections: savedUser.showTestConnections, + }; + } } diff --git a/backend/src/microservices/saas-microservice/use-cases/register-user-with-saml-use.case.ts b/backend/src/microservices/saas-microservice/use-cases/register-user-with-saml-use.case.ts index bbe8b6fc3..73b9b85cb 100644 --- a/backend/src/microservices/saas-microservice/use-cases/register-user-with-saml-use.case.ts +++ b/backend/src/microservices/saas-microservice/use-cases/register-user-with-saml-use.case.ts @@ -11,46 +11,46 @@ import { SaasSAMLUserRegisterDS } from '../data-structures/saas-saml-user-regist @Injectable() export class SaaSRegisterUserWIthSamlUseCase extends AbstractUseCase { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - public async implementation(inputData: SaasSAMLUserRegisterDS): Promise { - const { email, name, samlNameId, companyId } = inputData; - const foundUser = await this._dbContext.userRepository.findOneUserByEmail( - email, - ExternalRegistrationProviderEnum.SAML, - samlNameId, - ); - if (foundUser) { - return foundUser; - } + public async implementation(inputData: SaasSAMLUserRegisterDS): Promise { + const { email, name, samlNameId, companyId } = inputData; + const foundUser = await this._dbContext.userRepository.findOneUserByEmail( + email, + ExternalRegistrationProviderEnum.SAML, + samlNameId, + ); + if (foundUser) { + return foundUser; + } - const userData: RegisterUserDs = { - email: email, - password: null, - isActive: true, - name: name ? name : null, - gclidValue: null, - }; + const userData: RegisterUserDs = { + email: email, + password: null, + isActive: true, + name: name ? name : null, + gclidValue: null, + }; - const savedUser = await this._dbContext.userRepository.saveRegisteringUser( - userData, - ExternalRegistrationProviderEnum.SAML, - ); + const savedUser = await this._dbContext.userRepository.saveRegisteringUser( + userData, + ExternalRegistrationProviderEnum.SAML, + ); - const foundCompanyInfo = await this._dbContext.companyInfoRepository.findOne({ where: { id: companyId } }); - if (!foundCompanyInfo) { - throw new NotFoundException(Messages.COMPANY_NOT_FOUND); - } + const foundCompanyInfo = await this._dbContext.companyInfoRepository.findOne({ where: { id: companyId } }); + if (!foundCompanyInfo) { + throw new NotFoundException(Messages.COMPANY_NOT_FOUND); + } - savedUser.company = foundCompanyInfo; - savedUser.samlNameId = samlNameId; - savedUser.role = UserRoleEnum.USER; + savedUser.company = foundCompanyInfo; + savedUser.samlNameId = samlNameId; + savedUser.role = UserRoleEnum.USER; - return await this._dbContext.userRepository.saveUserEntity(savedUser); - } + return await this._dbContext.userRepository.saveUserEntity(savedUser); + } } diff --git a/backend/src/microservices/saas-microservice/use-cases/saas-use-cases.interface.ts b/backend/src/microservices/saas-microservice/use-cases/saas-use-cases.interface.ts index b619efcc4..438cadd9c 100644 --- a/backend/src/microservices/saas-microservice/use-cases/saas-use-cases.interface.ts +++ b/backend/src/microservices/saas-microservice/use-cases/saas-use-cases.interface.ts @@ -16,53 +16,53 @@ import { SaasRegisterUserWithGoogleDS } from '../data-structures/sass-register-u import { SuspendUsersDS } from '../data-structures/suspend-users.ds.js'; export interface ICompanyRegistration { - execute(inputData: RegisterCompanyWebhookDS): Promise; + execute(inputData: RegisterCompanyWebhookDS): Promise; } export interface IGetUserInfo { - execute(userData: GetUserInfoByIdDS): Promise; + execute(userData: GetUserInfoByIdDS): Promise; } export interface ISaasGetUsersInfosByEmail { - execute(userData: GetUsersInfosByEmailDS): Promise; + execute(userData: GetUsersInfosByEmailDS): Promise; } export interface ISaasRegisterUser { - execute(userData: SaasUsualUserRegisterDS): Promise; + execute(userData: SaasUsualUserRegisterDS): Promise; } export interface ISaasDemoRegisterUser { - execute(userData: SaaSRegisterDemoUserAccountDS): Promise; + execute(userData: SaaSRegisterDemoUserAccountDS): Promise; } export interface ILoginUserWithGoogle { - execute(inputData: SaasRegisterUserWithGoogleDS, inTransaction: InTransactionEnum): Promise; + execute(inputData: SaasRegisterUserWithGoogleDS, inTransaction: InTransactionEnum): Promise; } export interface ILoginUserWithGitHub { - execute(userData: SaasRegisterUserWithGithub): Promise; + execute(userData: SaasRegisterUserWithGithub): Promise; } export interface ISuspendUsers { - execute(usersData: SuspendUsersDS): Promise; + execute(usersData: SuspendUsersDS): Promise; } export interface ISuspendUsersOverLimit { - execute(companyId: string): Promise; + execute(companyId: string): Promise; } export interface ISaaSGetCompanyInfoByUserId { - execute(userId: string): Promise; + execute(userId: string): Promise; } export interface ISaaSGetUsersCountInCompany { - execute(companyId: string): Promise; + execute(companyId: string): Promise; } export interface IFreezeConnectionsInCompany { - execute(inputData: FreezeConnectionsInCompanyDS): Promise; + execute(inputData: FreezeConnectionsInCompanyDS): Promise; } export interface ISaasSAMLRegisterUser { - execute(userData: SaasSAMLUserRegisterDS): Promise; + execute(userData: SaasSAMLUserRegisterDS): Promise; } diff --git a/backend/src/microservices/saas-microservice/use-cases/suspend-users-over-limit.use.case.ts b/backend/src/microservices/saas-microservice/use-cases/suspend-users-over-limit.use.case.ts index ab9d98b43..7d597cb0b 100644 --- a/backend/src/microservices/saas-microservice/use-cases/suspend-users-over-limit.use.case.ts +++ b/backend/src/microservices/saas-microservice/use-cases/suspend-users-over-limit.use.case.ts @@ -2,29 +2,29 @@ import { Inject, Injectable } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import { ISuspendUsersOverLimit } from './saas-use-cases.interface.js'; import { Constants } from '../../../helpers/constants/constants.js'; import { slackPostMessage } from '../../../helpers/index.js'; +import { ISuspendUsersOverLimit } from './saas-use-cases.interface.js'; @Injectable() export class SuspendUsersOverLimitUseCase extends AbstractUseCase implements ISuspendUsersOverLimit { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(companyId: string): Promise { - const foundUsersInCompany = await this._dbContext.userRepository.findUsersInCompany(companyId, true); - const usersToSuspend = foundUsersInCompany.slice(Constants.FREE_PLAN_USERS_COUNT); + protected async implementation(companyId: string): Promise { + const foundUsersInCompany = await this._dbContext.userRepository.findUsersInCompany(companyId, true); + const usersToSuspend = foundUsersInCompany.slice(Constants.FREE_PLAN_USERS_COUNT); - if (usersToSuspend.length > 0) { - const userIdsToSuspend = usersToSuspend.map((user) => user.id); - await this._dbContext.userRepository.suspendUsers(userIdsToSuspend); - } - await slackPostMessage( - `SuspendUsersOverLimitUseCase: Company ID ${companyId} - Suspended ${usersToSuspend.length} user(s).`, - ); - } + if (usersToSuspend.length > 0) { + const userIdsToSuspend = usersToSuspend.map((user) => user.id); + await this._dbContext.userRepository.suspendUsers(userIdsToSuspend); + } + await slackPostMessage( + `SuspendUsersOverLimitUseCase: Company ID ${companyId} - Suspended ${usersToSuspend.length} user(s).`, + ); + } } diff --git a/backend/src/microservices/saas-microservice/use-cases/suspend-users.use.case.ts b/backend/src/microservices/saas-microservice/use-cases/suspend-users.use.case.ts index 650e62468..c25b18414 100644 --- a/backend/src/microservices/saas-microservice/use-cases/suspend-users.use.case.ts +++ b/backend/src/microservices/saas-microservice/use-cases/suspend-users.use.case.ts @@ -1,29 +1,29 @@ import { Inject, Injectable } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; +import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; +import { BaseType } from '../../../common/data-injection.tokens.js'; import { SuspendUsersDS } from '../data-structures/suspend-users.ds.js'; import { ISuspendUsers } from './saas-use-cases.interface.js'; -import { BaseType } from '../../../common/data-injection.tokens.js'; -import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; @Injectable() export class SuspendUsersUseCase extends AbstractUseCase implements ISuspendUsers { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: SuspendUsersDS): Promise { - const { emailsToSuspend, companyId } = inputData; - if (emailsToSuspend.length) { - const foundUsersToSuspend = await this._dbContext.userRepository.findUsersByEmailsAndCompanyId( - emailsToSuspend, - companyId, - ); - const foundUsersToSuspendIds = foundUsersToSuspend.map((user) => user.id); - await this._dbContext.userRepository.suspendUsers(foundUsersToSuspendIds); - } - await this._dbContext.userRepository.suspendNewestUsersInCompany(companyId, 3); - } + protected async implementation(inputData: SuspendUsersDS): Promise { + const { emailsToSuspend, companyId } = inputData; + if (emailsToSuspend.length) { + const foundUsersToSuspend = await this._dbContext.userRepository.findUsersByEmailsAndCompanyId( + emailsToSuspend, + companyId, + ); + const foundUsersToSuspendIds = foundUsersToSuspend.map((user) => user.id); + await this._dbContext.userRepository.suspendUsers(foundUsersToSuspendIds); + } + await this._dbContext.userRepository.suspendNewestUsersInCompany(companyId, 3); + } } diff --git a/backend/src/microservices/saas-microservice/use-cases/unfreeze-connections-in-company-use.case.ts b/backend/src/microservices/saas-microservice/use-cases/unfreeze-connections-in-company-use.case.ts index cb1493d1b..0748e9aa4 100644 --- a/backend/src/microservices/saas-microservice/use-cases/unfreeze-connections-in-company-use.case.ts +++ b/backend/src/microservices/saas-microservice/use-cases/unfreeze-connections-in-company-use.case.ts @@ -1,29 +1,29 @@ import { Inject, Injectable, Scope } from '@nestjs/common'; +import AbstractUseCase from '../../../common/abstract-use.case.js'; +import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; +import { BaseType } from '../../../common/data-injection.tokens.js'; import { SuccessResponse } from '../data-structures/common-responce.ds.js'; import { FreezeConnectionsInCompanyDS } from '../data-structures/freeze-connections-in-company.ds.js'; import { IFreezeConnectionsInCompany } from './saas-use-cases.interface.js'; -import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; -import { BaseType } from '../../../common/data-injection.tokens.js'; -import AbstractUseCase from '../../../common/abstract-use.case.js'; @Injectable({ scope: Scope.REQUEST }) export class UnFreezeConnectionsInCompanyUseCase - extends AbstractUseCase - implements IFreezeConnectionsInCompany + extends AbstractUseCase + implements IFreezeConnectionsInCompany { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(inputData: FreezeConnectionsInCompanyDS): Promise { - const { companyIds } = inputData; - const companyPaidConnections = - await this._dbContext.companyInfoRepository.findCompanyFrozenPaidConnections(companyIds); - const connectionsIds = companyPaidConnections.map((connection) => connection.id); - await this._dbContext.connectionRepository.unFreezeConnections(connectionsIds); - return { success: true }; - } + protected async implementation(inputData: FreezeConnectionsInCompanyDS): Promise { + const { companyIds } = inputData; + const companyPaidConnections = + await this._dbContext.companyInfoRepository.findCompanyFrozenPaidConnections(companyIds); + const connectionsIds = companyPaidConnections.map((connection) => connection.id); + await this._dbContext.connectionRepository.unFreezeConnections(connectionsIds); + return { success: true }; + } } diff --git a/backend/src/middlewares/logging-middleware/app-logger-middlewate.ts b/backend/src/middlewares/logging-middleware/app-logger-middlewate.ts index 08fa22190..95d8dab1a 100644 --- a/backend/src/middlewares/logging-middleware/app-logger-middlewate.ts +++ b/backend/src/middlewares/logging-middleware/app-logger-middlewate.ts @@ -4,21 +4,21 @@ import { WinstonLogger } from '../../entities/logging/winston-logger.js'; @Injectable() export class AppLoggerMiddleware implements NestMiddleware { - constructor(private readonly logger: WinstonLogger) {} + constructor(private readonly logger: WinstonLogger) {} - use(request: Request, response: Response, next: NextFunction): void { - const { ip, method, path: url, baseUrl } = request; - const userAgent = request.get('user-agent') || ''; - this.logger.info(`START ${method} ${url}${baseUrl} - ${userAgent} ${ip}`, { context: 'HTTP' }); - response.on('close', () => { - const { statusCode } = response; - const contentLength = response.get('content-length'); - this.logger.info( - `method: ${method}, url: ${url}, statusCode: ${statusCode}, contentLength: ${contentLength}, userAgent: ${userAgent}, ip: ${ip}`, - { context: 'HTTP' }, - ); - }); + use(request: Request, response: Response, next: NextFunction): void { + const { ip, method, path: url, baseUrl } = request; + const userAgent = request.get('user-agent') || ''; + this.logger.info(`START ${method} ${url}${baseUrl} - ${userAgent} ${ip}`, { context: 'HTTP' }); + response.on('close', () => { + const { statusCode } = response; + const contentLength = response.get('content-length'); + this.logger.info( + `method: ${method}, url: ${url}, statusCode: ${statusCode}, contentLength: ${contentLength}, userAgent: ${userAgent}, ip: ${ip}`, + { context: 'HTTP' }, + ); + }); - next(); - } + next(); + } } diff --git a/backend/src/migrations/1594021894551-InitialMigration.ts b/backend/src/migrations/1594021894551-InitialMigration.ts index 6ba029740..0441930d3 100644 --- a/backend/src/migrations/1594021894551-InitialMigration.ts +++ b/backend/src/migrations/1594021894551-InitialMigration.ts @@ -1,46 +1,73 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class InitialMigration1594021894551 implements MigrationInterface { - name = 'InitialMigration1594021894551' + name = 'InitialMigration1594021894551'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "permission" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "type" character varying NOT NULL, "accessLevel" character varying NOT NULL, "tableName" character varying NOT NULL DEFAULT '', CONSTRAINT "PK_3b8b97af9d9d8807e41e6f48362" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TABLE "group" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "title" character varying NOT NULL, "connectionId" uuid, CONSTRAINT "UQ_c5dcbf6b8ecf068f959a367dc9e" UNIQUE ("connectionId", "title"), CONSTRAINT "PK_256aa0fda9b1de1a73ee0b7106b" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TABLE "user" ("id" uuid NOT NULL, "isActive" boolean NOT NULL DEFAULT true, CONSTRAINT "PK_cace4a159ff9f2512dd42373760" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TABLE "connection" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "description" character varying NOT NULL DEFAULT '', "type" character varying NOT NULL, "host" character varying NOT NULL, "port" integer NOT NULL, "username" character varying NOT NULL, "password" character varying NOT NULL, "database" character varying NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "authorId" uuid, CONSTRAINT "PK_be611ce8b8cf439091c82a334b2" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TABLE "table" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), CONSTRAINT "PK_28914b55c485fc2d7a101b1b2a4" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TABLE "permission_groups_group" ("permissionId" uuid NOT NULL, "groupId" uuid NOT NULL, CONSTRAINT "PK_6fa192288ad79f889c117f7edc1" PRIMARY KEY ("permissionId", "groupId"))`); - await queryRunner.query(`CREATE INDEX "IDX_0dd43db7f5e646262978c3ad0a" ON "permission_groups_group" ("permissionId") `); - await queryRunner.query(`CREATE INDEX "IDX_b78f7697f5b985fc4f40615aaf" ON "permission_groups_group" ("groupId") `); - await queryRunner.query(`CREATE TABLE "user_groups_group" ("userId" uuid NOT NULL, "groupId" uuid NOT NULL, CONSTRAINT "PK_98d481413dbe5578ad2a45ab863" PRIMARY KEY ("userId", "groupId"))`); - await queryRunner.query(`CREATE INDEX "IDX_84ff6a520aee2bf2512c01cf46" ON "user_groups_group" ("userId") `); - await queryRunner.query(`CREATE INDEX "IDX_8abdfe8f9d78a4f5e821dbf620" ON "user_groups_group" ("groupId") `); - await queryRunner.query(`ALTER TABLE "group" ADD CONSTRAINT "FK_fad2f67fd9597d6b81b401f2fa3" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "permission_groups_group" ADD CONSTRAINT "FK_0dd43db7f5e646262978c3ad0aa" FOREIGN KEY ("permissionId") REFERENCES "permission"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "permission_groups_group" ADD CONSTRAINT "FK_b78f7697f5b985fc4f40615aaf9" FOREIGN KEY ("groupId") REFERENCES "group"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "user_groups_group" ADD CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "user_groups_group" ADD CONSTRAINT "FK_8abdfe8f9d78a4f5e821dbf6203" FOREIGN KEY ("groupId") REFERENCES "group"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_groups_group" DROP CONSTRAINT "FK_8abdfe8f9d78a4f5e821dbf6203"`); - await queryRunner.query(`ALTER TABLE "user_groups_group" DROP CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462"`); - await queryRunner.query(`ALTER TABLE "permission_groups_group" DROP CONSTRAINT "FK_b78f7697f5b985fc4f40615aaf9"`); - await queryRunner.query(`ALTER TABLE "permission_groups_group" DROP CONSTRAINT "FK_0dd43db7f5e646262978c3ad0aa"`); - await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); - await queryRunner.query(`ALTER TABLE "group" DROP CONSTRAINT "FK_fad2f67fd9597d6b81b401f2fa3"`); - await queryRunner.query(`DROP INDEX "IDX_8abdfe8f9d78a4f5e821dbf620"`); - await queryRunner.query(`DROP INDEX "IDX_84ff6a520aee2bf2512c01cf46"`); - await queryRunner.query(`DROP TABLE "user_groups_group"`); - await queryRunner.query(`DROP INDEX "IDX_b78f7697f5b985fc4f40615aaf"`); - await queryRunner.query(`DROP INDEX "IDX_0dd43db7f5e646262978c3ad0a"`); - await queryRunner.query(`DROP TABLE "permission_groups_group"`); - await queryRunner.query(`DROP TABLE "table"`); - await queryRunner.query(`DROP TABLE "connection"`); - await queryRunner.query(`DROP TABLE "user"`); - await queryRunner.query(`DROP TABLE "group"`); - await queryRunner.query(`DROP TABLE "permission"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "permission" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "type" character varying NOT NULL, "accessLevel" character varying NOT NULL, "tableName" character varying NOT NULL DEFAULT '', CONSTRAINT "PK_3b8b97af9d9d8807e41e6f48362" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "group" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "title" character varying NOT NULL, "connectionId" uuid, CONSTRAINT "UQ_c5dcbf6b8ecf068f959a367dc9e" UNIQUE ("connectionId", "title"), CONSTRAINT "PK_256aa0fda9b1de1a73ee0b7106b" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "user" ("id" uuid NOT NULL, "isActive" boolean NOT NULL DEFAULT true, CONSTRAINT "PK_cace4a159ff9f2512dd42373760" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "connection" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "description" character varying NOT NULL DEFAULT '', "type" character varying NOT NULL, "host" character varying NOT NULL, "port" integer NOT NULL, "username" character varying NOT NULL, "password" character varying NOT NULL, "database" character varying NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "authorId" uuid, CONSTRAINT "PK_be611ce8b8cf439091c82a334b2" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "table" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), CONSTRAINT "PK_28914b55c485fc2d7a101b1b2a4" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "permission_groups_group" ("permissionId" uuid NOT NULL, "groupId" uuid NOT NULL, CONSTRAINT "PK_6fa192288ad79f889c117f7edc1" PRIMARY KEY ("permissionId", "groupId"))`, + ); + await queryRunner.query( + `CREATE INDEX "IDX_0dd43db7f5e646262978c3ad0a" ON "permission_groups_group" ("permissionId") `, + ); + await queryRunner.query(`CREATE INDEX "IDX_b78f7697f5b985fc4f40615aaf" ON "permission_groups_group" ("groupId") `); + await queryRunner.query( + `CREATE TABLE "user_groups_group" ("userId" uuid NOT NULL, "groupId" uuid NOT NULL, CONSTRAINT "PK_98d481413dbe5578ad2a45ab863" PRIMARY KEY ("userId", "groupId"))`, + ); + await queryRunner.query(`CREATE INDEX "IDX_84ff6a520aee2bf2512c01cf46" ON "user_groups_group" ("userId") `); + await queryRunner.query(`CREATE INDEX "IDX_8abdfe8f9d78a4f5e821dbf620" ON "user_groups_group" ("groupId") `); + await queryRunner.query( + `ALTER TABLE "group" ADD CONSTRAINT "FK_fad2f67fd9597d6b81b401f2fa3" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "permission_groups_group" ADD CONSTRAINT "FK_0dd43db7f5e646262978c3ad0aa" FOREIGN KEY ("permissionId") REFERENCES "permission"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "permission_groups_group" ADD CONSTRAINT "FK_b78f7697f5b985fc4f40615aaf9" FOREIGN KEY ("groupId") REFERENCES "group"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "user_groups_group" ADD CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "user_groups_group" ADD CONSTRAINT "FK_8abdfe8f9d78a4f5e821dbf6203" FOREIGN KEY ("groupId") REFERENCES "group"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user_groups_group" DROP CONSTRAINT "FK_8abdfe8f9d78a4f5e821dbf6203"`); + await queryRunner.query(`ALTER TABLE "user_groups_group" DROP CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462"`); + await queryRunner.query(`ALTER TABLE "permission_groups_group" DROP CONSTRAINT "FK_b78f7697f5b985fc4f40615aaf9"`); + await queryRunner.query(`ALTER TABLE "permission_groups_group" DROP CONSTRAINT "FK_0dd43db7f5e646262978c3ad0aa"`); + await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); + await queryRunner.query(`ALTER TABLE "group" DROP CONSTRAINT "FK_fad2f67fd9597d6b81b401f2fa3"`); + await queryRunner.query(`DROP INDEX "IDX_8abdfe8f9d78a4f5e821dbf620"`); + await queryRunner.query(`DROP INDEX "IDX_84ff6a520aee2bf2512c01cf46"`); + await queryRunner.query(`DROP TABLE "user_groups_group"`); + await queryRunner.query(`DROP INDEX "IDX_b78f7697f5b985fc4f40615aaf"`); + await queryRunner.query(`DROP INDEX "IDX_0dd43db7f5e646262978c3ad0a"`); + await queryRunner.query(`DROP TABLE "permission_groups_group"`); + await queryRunner.query(`DROP TABLE "table"`); + await queryRunner.query(`DROP TABLE "connection"`); + await queryRunner.query(`DROP TABLE "user"`); + await queryRunner.query(`DROP TABLE "group"`); + await queryRunner.query(`DROP TABLE "permission"`); + } } diff --git a/backend/src/migrations/1597314058608-AddSID.ts b/backend/src/migrations/1597314058608-AddSID.ts index da127dfa9..7f742ff04 100644 --- a/backend/src/migrations/1597314058608-AddSID.ts +++ b/backend/src/migrations/1597314058608-AddSID.ts @@ -1,14 +1,13 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddSID1597314058608 implements MigrationInterface { - name = 'AddSID1597314058608' + name = 'AddSID1597314058608'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" ADD COLUMN "sid" VARCHAR(255) DEFAULT NULL`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "sid"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" ADD COLUMN "sid" VARCHAR(255) DEFAULT NULL`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "sid"`); + } } diff --git a/backend/src/migrations/1599721879444-CreateTableSettings.ts b/backend/src/migrations/1599721879444-CreateTableSettings.ts index 5d490d641..76d61907f 100644 --- a/backend/src/migrations/1599721879444-CreateTableSettings.ts +++ b/backend/src/migrations/1599721879444-CreateTableSettings.ts @@ -1,20 +1,23 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class CreateTableSettings1599721879444 implements MigrationInterface { - name = 'CreateTableSettings1599721879444' + name = 'CreateTableSettings1599721879444'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TYPE "tableSettings_ordering_enum" AS ENUM('ASC', 'DESC')`); - await queryRunner.query(`CREATE TABLE "tableSettings" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "table_name" character varying DEFAULT null, "display_name" character varying DEFAULT null, "search_fields" character varying array NOT NULL DEFAULT '{}', "excluded_fields" character varying array NOT NULL DEFAULT '{}', "list_fields" character varying array NOT NULL DEFAULT '{}', "list_per_page" integer DEFAULT null, "ordering" "tableSettings_ordering_enum" NOT NULL DEFAULT 'ASC', "ordering_field" character varying DEFAULT null, "readonly_fields" character varying array NOT NULL DEFAULT '{}', "sortable_by" character varying array NOT NULL DEFAULT '{}', "connectionIdId" uuid, CONSTRAINT "UQ_5a62e8aec5c74174d8355c34b70" UNIQUE ("connectionIdId", "table_name"), CONSTRAINT "PK_bf3b951c0d7bd0e4e11a5d9ffba" PRIMARY KEY ("id"))`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sid" SET DEFAULT null`); - await queryRunner.query(`ALTER TABLE "tableSettings" ADD CONSTRAINT "FK_e959bd443a42403e4a76dcdcbef" FOREIGN KEY ("connectionIdId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableSettings" DROP CONSTRAINT "FK_e959bd443a42403e4a76dcdcbef"`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sid" SET DEFAULT NULL`); - await queryRunner.query(`DROP TABLE "tableSettings"`); - await queryRunner.query(`DROP TYPE "tableSettings_ordering_enum"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TYPE "tableSettings_ordering_enum" AS ENUM('ASC', 'DESC')`); + await queryRunner.query( + `CREATE TABLE "tableSettings" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "table_name" character varying DEFAULT null, "display_name" character varying DEFAULT null, "search_fields" character varying array NOT NULL DEFAULT '{}', "excluded_fields" character varying array NOT NULL DEFAULT '{}', "list_fields" character varying array NOT NULL DEFAULT '{}', "list_per_page" integer DEFAULT null, "ordering" "tableSettings_ordering_enum" NOT NULL DEFAULT 'ASC', "ordering_field" character varying DEFAULT null, "readonly_fields" character varying array NOT NULL DEFAULT '{}', "sortable_by" character varying array NOT NULL DEFAULT '{}', "connectionIdId" uuid, CONSTRAINT "UQ_5a62e8aec5c74174d8355c34b70" UNIQUE ("connectionIdId", "table_name"), CONSTRAINT "PK_bf3b951c0d7bd0e4e11a5d9ffba" PRIMARY KEY ("id"))`, + ); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sid" SET DEFAULT null`); + await queryRunner.query( + `ALTER TABLE "tableSettings" ADD CONSTRAINT "FK_e959bd443a42403e4a76dcdcbef" FOREIGN KEY ("connectionIdId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableSettings" DROP CONSTRAINT "FK_e959bd443a42403e4a76dcdcbef"`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sid" SET DEFAULT NULL`); + await queryRunner.query(`DROP TABLE "tableSettings"`); + await queryRunner.query(`DROP TYPE "tableSettings_ordering_enum"`); + } } diff --git a/backend/src/migrations/1603111362543-EnableFirstLevelEncryption.ts b/backend/src/migrations/1603111362543-EnableFirstLevelEncryption.ts index 7acfd0f06..34e64773d 100644 --- a/backend/src/migrations/1603111362543-EnableFirstLevelEncryption.ts +++ b/backend/src/migrations/1603111362543-EnableFirstLevelEncryption.ts @@ -1,26 +1,29 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class EnableFirstLevelEncryption1603111362543 implements MigrationInterface { - name = 'EnableFirstLevelEncryption1603111362543' + name = 'EnableFirstLevelEncryption1603111362543'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableSettings" DROP CONSTRAINT "UQ_5a62e8aec5c74174d8355c34b70"`); - await queryRunner.query(`ALTER TABLE "tableSettings" ALTER COLUMN "table_name" SET DEFAULT null`); - await queryRunner.query(`ALTER TABLE "tableSettings" ALTER COLUMN "display_name" SET DEFAULT null`); - await queryRunner.query(`ALTER TABLE "tableSettings" ALTER COLUMN "list_per_page" SET DEFAULT null`); - await queryRunner.query(`ALTER TABLE "tableSettings" ALTER COLUMN "ordering_field" SET DEFAULT null`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sid" SET DEFAULT null`); - await queryRunner.query(`ALTER TABLE "tableSettings" ADD CONSTRAINT "UQ_5a62e8aec5c74174d8355c34b70" UNIQUE ("connectionIdId", "table_name")`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableSettings" DROP CONSTRAINT "UQ_5a62e8aec5c74174d8355c34b70"`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sid" SET DEFAULT NULL`); - await queryRunner.query(`ALTER TABLE "tableSettings" ALTER COLUMN "ordering_field" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "tableSettings" ALTER COLUMN "list_per_page" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "tableSettings" ALTER COLUMN "display_name" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "tableSettings" ALTER COLUMN "table_name" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "tableSettings" ADD CONSTRAINT "UQ_5a62e8aec5c74174d8355c34b70" UNIQUE ("table_name", "connectionIdId")`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableSettings" DROP CONSTRAINT "UQ_5a62e8aec5c74174d8355c34b70"`); + await queryRunner.query(`ALTER TABLE "tableSettings" ALTER COLUMN "table_name" SET DEFAULT null`); + await queryRunner.query(`ALTER TABLE "tableSettings" ALTER COLUMN "display_name" SET DEFAULT null`); + await queryRunner.query(`ALTER TABLE "tableSettings" ALTER COLUMN "list_per_page" SET DEFAULT null`); + await queryRunner.query(`ALTER TABLE "tableSettings" ALTER COLUMN "ordering_field" SET DEFAULT null`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sid" SET DEFAULT null`); + await queryRunner.query( + `ALTER TABLE "tableSettings" ADD CONSTRAINT "UQ_5a62e8aec5c74174d8355c34b70" UNIQUE ("connectionIdId", "table_name")`, + ); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableSettings" DROP CONSTRAINT "UQ_5a62e8aec5c74174d8355c34b70"`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sid" SET DEFAULT NULL`); + await queryRunner.query(`ALTER TABLE "tableSettings" ALTER COLUMN "ordering_field" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "tableSettings" ALTER COLUMN "list_per_page" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "tableSettings" ALTER COLUMN "display_name" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "tableSettings" ALTER COLUMN "table_name" DROP DEFAULT`); + await queryRunner.query( + `ALTER TABLE "tableSettings" ADD CONSTRAINT "UQ_5a62e8aec5c74174d8355c34b70" UNIQUE ("table_name", "connectionIdId")`, + ); + } } diff --git a/backend/src/migrations/1603892873380-AddSSHPropertiesInConnectionEntity.ts b/backend/src/migrations/1603892873380-AddSSHPropertiesInConnectionEntity.ts index db05926eb..9e03c3797 100644 --- a/backend/src/migrations/1603892873380-AddSSHPropertiesInConnectionEntity.ts +++ b/backend/src/migrations/1603892873380-AddSSHPropertiesInConnectionEntity.ts @@ -1,23 +1,21 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddSSHPropertiesInConnectionEntity1603892873380 implements MigrationInterface { - name = 'AddSSHPropertiesInConnectionEntity1603892873380' + name = 'AddSSHPropertiesInConnectionEntity1603892873380'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" ADD "ssh" boolean NOT NULL DEFAULT false`); - await queryRunner.query(`ALTER TABLE "connection" ADD "privateSSHKey" character varying DEFAULT null`); - await queryRunner.query(`ALTER TABLE "connection" ADD "sshHost" character varying DEFAULT null`); - await queryRunner.query(`ALTER TABLE "connection" ADD "sshPort" integer DEFAULT null`); - await queryRunner.query(`ALTER TABLE "connection" ADD "sshUsername" character varying DEFAULT null`); - - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "sshUsername"`); - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "sshPort"`); - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "sshHost"`); - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "privateSSHKey"`); - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "ssh"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" ADD "ssh" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`ALTER TABLE "connection" ADD "privateSSHKey" character varying DEFAULT null`); + await queryRunner.query(`ALTER TABLE "connection" ADD "sshHost" character varying DEFAULT null`); + await queryRunner.query(`ALTER TABLE "connection" ADD "sshPort" integer DEFAULT null`); + await queryRunner.query(`ALTER TABLE "connection" ADD "sshUsername" character varying DEFAULT null`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "sshUsername"`); + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "sshPort"`); + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "sshHost"`); + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "privateSSHKey"`); + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "ssh"`); + } } diff --git a/backend/src/migrations/1605105702167-AddAutocompleteColumnsInTableSettings.ts b/backend/src/migrations/1605105702167-AddAutocompleteColumnsInTableSettings.ts index 8e4f6b312..7502ef83e 100644 --- a/backend/src/migrations/1605105702167-AddAutocompleteColumnsInTableSettings.ts +++ b/backend/src/migrations/1605105702167-AddAutocompleteColumnsInTableSettings.ts @@ -1,14 +1,15 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddAutocompleteColumnsInTableSettings1605105702167 implements MigrationInterface { - name = 'AddAutocompleteColumnsInTableSettings1605105702167' + name = 'AddAutocompleteColumnsInTableSettings1605105702167'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableSettings" ADD "autocomplete_columns" character varying array NOT NULL DEFAULT '{}'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "autocomplete_columns"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "tableSettings" ADD "autocomplete_columns" character varying array NOT NULL DEFAULT '{}'`, + ); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "autocomplete_columns"`); + } } diff --git a/backend/src/migrations/1608192478936-AddTableLogs.ts b/backend/src/migrations/1608192478936-AddTableLogs.ts index b14ef3950..b4a8a92cb 100644 --- a/backend/src/migrations/1608192478936-AddTableLogs.ts +++ b/backend/src/migrations/1608192478936-AddTableLogs.ts @@ -1,20 +1,27 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddTableLogs1608192478936 implements MigrationInterface { - name = 'AddTableLogs1608192478936' + name = 'AddTableLogs1608192478936'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TYPE "tableLogs_operationtype_enum" AS ENUM('addRow', 'updateRow', 'deleteRow', 'unknown')`); - await queryRunner.query(`CREATE TYPE "tableLogs_operationstatusresult_enum" AS ENUM('successfully', 'unsuccessfully', 'unknown')`); - await queryRunner.query(`CREATE TABLE "tableLogs" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "table_name" character varying DEFAULT null, "received_data" character varying DEFAULT null, "cognitoUserName" character varying DEFAULT null, "email" character varying DEFAULT null, "operationType" "tableLogs_operationtype_enum" NOT NULL DEFAULT 'unknown', "operationStatusResult" "tableLogs_operationstatusresult_enum" NOT NULL DEFAULT 'unknown', "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "connectionIdId" uuid, CONSTRAINT "PK_6ca1c0508e16757b5ce6f64cacf" PRIMARY KEY ("id"))`); - await queryRunner.query(`ALTER TABLE "tableLogs" ADD CONSTRAINT "FK_a5dd6c8c66dd42f16aa72b3afd3" FOREIGN KEY ("connectionIdId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableLogs" DROP CONSTRAINT "FK_a5dd6c8c66dd42f16aa72b3afd3"`); - await queryRunner.query(`DROP TABLE "tableLogs"`); - await queryRunner.query(`DROP TYPE "tableLogs_operationstatusresult_enum"`); - await queryRunner.query(`DROP TYPE "tableLogs_operationtype_enum"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TYPE "tableLogs_operationtype_enum" AS ENUM('addRow', 'updateRow', 'deleteRow', 'unknown')`, + ); + await queryRunner.query( + `CREATE TYPE "tableLogs_operationstatusresult_enum" AS ENUM('successfully', 'unsuccessfully', 'unknown')`, + ); + await queryRunner.query( + `CREATE TABLE "tableLogs" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "table_name" character varying DEFAULT null, "received_data" character varying DEFAULT null, "cognitoUserName" character varying DEFAULT null, "email" character varying DEFAULT null, "operationType" "tableLogs_operationtype_enum" NOT NULL DEFAULT 'unknown', "operationStatusResult" "tableLogs_operationstatusresult_enum" NOT NULL DEFAULT 'unknown', "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "connectionIdId" uuid, CONSTRAINT "PK_6ca1c0508e16757b5ce6f64cacf" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "tableLogs" ADD CONSTRAINT "FK_a5dd6c8c66dd42f16aa72b3afd3" FOREIGN KEY ("connectionIdId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableLogs" DROP CONSTRAINT "FK_a5dd6c8c66dd42f16aa72b3afd3"`); + await queryRunner.query(`DROP TABLE "tableLogs"`); + await queryRunner.query(`DROP TYPE "tableLogs_operationstatusresult_enum"`); + await queryRunner.query(`DROP TYPE "tableLogs_operationtype_enum"`); + } } diff --git a/backend/src/migrations/1608824174582-AddIsMainPropertyInGroupEntity.ts b/backend/src/migrations/1608824174582-AddIsMainPropertyInGroupEntity.ts index 3792bb0e9..ce5f86392 100644 --- a/backend/src/migrations/1608824174582-AddIsMainPropertyInGroupEntity.ts +++ b/backend/src/migrations/1608824174582-AddIsMainPropertyInGroupEntity.ts @@ -1,14 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddIsMainPropertyInGroupEntity1608824174582 implements MigrationInterface { - name = 'AddIsMainPropertyInGroupEntity1608824174582'; + name = 'AddIsMainPropertyInGroupEntity1608824174582'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "group" ADD "isMain" boolean NOT NULL DEFAULT false`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "group" DROP COLUMN "isMain"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "group" ADD "isMain" boolean NOT NULL DEFAULT false`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "group" DROP COLUMN "isMain"`); + } } diff --git a/backend/src/migrations/1609869402512-RenamePropertyDescriptionToTitleInConnectionEntity.ts b/backend/src/migrations/1609869402512-RenamePropertyDescriptionToTitleInConnectionEntity.ts index dba1a4f27..11d507f6c 100644 --- a/backend/src/migrations/1609869402512-RenamePropertyDescriptionToTitleInConnectionEntity.ts +++ b/backend/src/migrations/1609869402512-RenamePropertyDescriptionToTitleInConnectionEntity.ts @@ -1,14 +1,13 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class RenamePropertyDescriptionToTitleInConnectionEntity1609869402512 implements MigrationInterface { - name = 'RenamePropertyDescriptionToTitleInConnectionEntity1609869402512' + name = 'RenamePropertyDescriptionToTitleInConnectionEntity1609869402512'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" RENAME COLUMN "description" TO "title"`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" RENAME COLUMN "title" TO "description"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" RENAME COLUMN "description" TO "title"`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" RENAME COLUMN "title" TO "description"`); + } } diff --git a/backend/src/migrations/1610446934945-AddMasterEncryption.ts b/backend/src/migrations/1610446934945-AddMasterEncryption.ts index 689d094ee..36b8a618e 100644 --- a/backend/src/migrations/1610446934945-AddMasterEncryption.ts +++ b/backend/src/migrations/1610446934945-AddMasterEncryption.ts @@ -1,14 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddMasterEncryption1610446934945 implements MigrationInterface { - name = 'AddMasterEncryption1610446934945'; + name = 'AddMasterEncryption1610446934945'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" ADD "masterEncryption" boolean NOT NULL DEFAULT false`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "masterEncryption"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" ADD "masterEncryption" boolean NOT NULL DEFAULT false`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "masterEncryption"`); + } } diff --git a/backend/src/migrations/1610729633595-AddColumnCreatedAtInUserEntity.ts b/backend/src/migrations/1610729633595-AddColumnCreatedAtInUserEntity.ts index c09561c10..c034c355a 100644 --- a/backend/src/migrations/1610729633595-AddColumnCreatedAtInUserEntity.ts +++ b/backend/src/migrations/1610729633595-AddColumnCreatedAtInUserEntity.ts @@ -1,14 +1,13 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddColumnCreatedAtInUserEntity1610729633595 implements MigrationInterface { - name = 'AddColumnCreatedAtInUserEntity1610729633595' + name = 'AddColumnCreatedAtInUserEntity1610729633595'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" ADD "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "createdAt"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" ADD "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "createdAt"`); + } } diff --git a/backend/src/migrations/1611562808409-AddSslPropertiesInConnectionEntity.ts b/backend/src/migrations/1611562808409-AddSslPropertiesInConnectionEntity.ts index a610aaa0a..e748623ad 100644 --- a/backend/src/migrations/1611562808409-AddSslPropertiesInConnectionEntity.ts +++ b/backend/src/migrations/1611562808409-AddSslPropertiesInConnectionEntity.ts @@ -1,16 +1,15 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddSslPropertiesInConnectionEntity1611562808409 implements MigrationInterface { - name = 'AddSslPropertiesInConnectionEntity1611562808409'; + name = 'AddSslPropertiesInConnectionEntity1611562808409'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" ADD "ssl" boolean NOT NULL DEFAULT false`); - await queryRunner.query(`ALTER TABLE "connection" ADD "cert" character varying DEFAULT null`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "cert"`); - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "ssl"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" ADD "ssl" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`ALTER TABLE "connection" ADD "cert" character varying DEFAULT null`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "cert"`); + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "ssl"`); + } } diff --git a/backend/src/migrations/1613652980675-AddGclidColumnInUserEntity.ts b/backend/src/migrations/1613652980675-AddGclidColumnInUserEntity.ts index e5d14f6f6..5b470bf1b 100644 --- a/backend/src/migrations/1613652980675-AddGclidColumnInUserEntity.ts +++ b/backend/src/migrations/1613652980675-AddGclidColumnInUserEntity.ts @@ -1,14 +1,13 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddGclidColumnInUserEntity1613652980675 implements MigrationInterface { - name = 'AddGclidColumnInUserEntity1613652980675' + name = 'AddGclidColumnInUserEntity1613652980675'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" ADD "gclid" character varying DEFAULT null`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "gclid"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" ADD "gclid" character varying DEFAULT null`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "gclid"`); + } } diff --git a/backend/src/migrations/1614186081075-CreateCustomFieldsEntity.ts b/backend/src/migrations/1614186081075-CreateCustomFieldsEntity.ts index 8b727c354..1a6910bba 100644 --- a/backend/src/migrations/1614186081075-CreateCustomFieldsEntity.ts +++ b/backend/src/migrations/1614186081075-CreateCustomFieldsEntity.ts @@ -1,16 +1,19 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class CreateCustomFieldsEntity1614186081075 implements MigrationInterface { - name = 'CreateCustomFieldsEntity1614186081075' + name = 'CreateCustomFieldsEntity1614186081075'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "customFields" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "type" character varying NOT NULL, "template_string" character varying NOT NULL, "text" character varying NOT NULL, "settingsId" uuid, CONSTRAINT "PK_94cb2a5e19fec9795de86dde31f" PRIMARY KEY ("id"))`); - await queryRunner.query(`ALTER TABLE "customFields" ADD CONSTRAINT "FK_240d8dd07936ff4758e650a52f3" FOREIGN KEY ("settingsId") REFERENCES "tableSettings"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "customFields" DROP CONSTRAINT "FK_240d8dd07936ff4758e650a52f3"`); - await queryRunner.query(`DROP TABLE "customFields"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "customFields" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "type" character varying NOT NULL, "template_string" character varying NOT NULL, "text" character varying NOT NULL, "settingsId" uuid, CONSTRAINT "PK_94cb2a5e19fec9795de86dde31f" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "customFields" ADD CONSTRAINT "FK_240d8dd07936ff4758e650a52f3" FOREIGN KEY ("settingsId") REFERENCES "tableSettings"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "customFields" DROP CONSTRAINT "FK_240d8dd07936ff4758e650a52f3"`); + await queryRunner.query(`DROP TABLE "customFields"`); + } } diff --git a/backend/src/migrations/1616659494496-AddTableSchemaInConnectionEntity.ts b/backend/src/migrations/1616659494496-AddTableSchemaInConnectionEntity.ts index c075fee4b..a61f87147 100644 --- a/backend/src/migrations/1616659494496-AddTableSchemaInConnectionEntity.ts +++ b/backend/src/migrations/1616659494496-AddTableSchemaInConnectionEntity.ts @@ -1,14 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddTableSchemaInConnectionEntity1616659494496 implements MigrationInterface { - name = 'AddTableSchemaInConnectionEntity1616659494496'; + name = 'AddTableSchemaInConnectionEntity1616659494496'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" ADD "schema" character varying DEFAULT null`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "schema"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" ADD "schema" character varying DEFAULT null`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "schema"`); + } } diff --git a/backend/src/migrations/1617872481128-CreateTableWidgets.ts b/backend/src/migrations/1617872481128-CreateTableWidgets.ts index 003b8d222..1548c6333 100644 --- a/backend/src/migrations/1617872481128-CreateTableWidgets.ts +++ b/backend/src/migrations/1617872481128-CreateTableWidgets.ts @@ -1,16 +1,19 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class CreateTableWidgets1617872481128 implements MigrationInterface { - name = 'CreateTableWidgets1617872481128' + name = 'CreateTableWidgets1617872481128'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "table_widget" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "field_name" character varying NOT NULL, "widget_type" character varying NOT NULL, "widget_params" character varying array DEFAULT null, "settingsId" uuid, CONSTRAINT "PK_a75c33a535f559ab8d77aaedc51" PRIMARY KEY ("id"))`); - await queryRunner.query(`ALTER TABLE "table_widget" ADD CONSTRAINT "FK_ecc881f8a502dd987b36abdfd51" FOREIGN KEY ("settingsId") REFERENCES "tableSettings"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_widget" DROP CONSTRAINT "FK_ecc881f8a502dd987b36abdfd51"`); - await queryRunner.query(`DROP TABLE "table_widget"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "table_widget" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "field_name" character varying NOT NULL, "widget_type" character varying NOT NULL, "widget_params" character varying array DEFAULT null, "settingsId" uuid, CONSTRAINT "PK_a75c33a535f559ab8d77aaedc51" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "table_widget" ADD CONSTRAINT "FK_ecc881f8a502dd987b36abdfd51" FOREIGN KEY ("settingsId") REFERENCES "tableSettings"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_widget" DROP CONSTRAINT "FK_ecc881f8a502dd987b36abdfd51"`); + await queryRunner.query(`DROP TABLE "table_widget"`); + } } diff --git a/backend/src/migrations/1618929873956-AddNameDescriptionInWidgetsTable.ts b/backend/src/migrations/1618929873956-AddNameDescriptionInWidgetsTable.ts index 45a9d77e8..400863206 100644 --- a/backend/src/migrations/1618929873956-AddNameDescriptionInWidgetsTable.ts +++ b/backend/src/migrations/1618929873956-AddNameDescriptionInWidgetsTable.ts @@ -1,16 +1,15 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddNameDescriptionInWidgetsTable1618929873956 implements MigrationInterface { - name = 'AddNameDescriptionInWidgetsTable1618929873956'; + name = 'AddNameDescriptionInWidgetsTable1618929873956'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_widget" ADD "name" character varying DEFAULT null`); - await queryRunner.query(`ALTER TABLE "table_widget" ADD "description" character varying DEFAULT null`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_widget" DROP COLUMN "description"`); - await queryRunner.query(`ALTER TABLE "table_widget" DROP COLUMN "name"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_widget" ADD "name" character varying DEFAULT null`); + await queryRunner.query(`ALTER TABLE "table_widget" ADD "description" character varying DEFAULT null`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_widget" DROP COLUMN "description"`); + await queryRunner.query(`ALTER TABLE "table_widget" DROP COLUMN "name"`); + } } diff --git a/backend/src/migrations/1620130292385-AddOldDataFieldIntoTableLogsEntity.ts b/backend/src/migrations/1620130292385-AddOldDataFieldIntoTableLogsEntity.ts index e4842e44e..1b427ea43 100644 --- a/backend/src/migrations/1620130292385-AddOldDataFieldIntoTableLogsEntity.ts +++ b/backend/src/migrations/1620130292385-AddOldDataFieldIntoTableLogsEntity.ts @@ -1,14 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddOldDataFieldIntoTableLogsEntity1620130292385 implements MigrationInterface { - name = 'AddOldDataFieldIntoTableLogsEntity1620130292385'; + name = 'AddOldDataFieldIntoTableLogsEntity1620130292385'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableLogs" ADD "old_data" character varying DEFAULT null`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableLogs" DROP COLUMN "old_data"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableLogs" ADD "old_data" character varying DEFAULT null`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableLogs" DROP COLUMN "old_data"`); + } } diff --git a/backend/src/migrations/1620390981884-AddIdentificationFieldsIntoTableSettingsEntity.ts b/backend/src/migrations/1620390981884-AddIdentificationFieldsIntoTableSettingsEntity.ts index 10ac952aa..d9a75044f 100644 --- a/backend/src/migrations/1620390981884-AddIdentificationFieldsIntoTableSettingsEntity.ts +++ b/backend/src/migrations/1620390981884-AddIdentificationFieldsIntoTableSettingsEntity.ts @@ -1,14 +1,15 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddIdentificationFieldsIntoTableSettingsEntity1620390981884 implements MigrationInterface { - name = 'AddIdentificationFieldsIntoTableSettingsEntity1620390981884'; + name = 'AddIdentificationFieldsIntoTableSettingsEntity1620390981884'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableSettings" ADD "identification_fields" character varying array NOT NULL DEFAULT '{}'`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "identification_fields"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "tableSettings" ADD "identification_fields" character varying array NOT NULL DEFAULT '{}'`, + ); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "identification_fields"`); + } } diff --git a/backend/src/migrations/1622621082756-CreateAgentEntity.ts b/backend/src/migrations/1622621082756-CreateAgentEntity.ts index 96c72bee7..e72ca9a8d 100644 --- a/backend/src/migrations/1622621082756-CreateAgentEntity.ts +++ b/backend/src/migrations/1622621082756-CreateAgentEntity.ts @@ -1,15 +1,19 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class CreateAgentEntity1622621082756 implements MigrationInterface { - name = 'CreateAgentEntity1622621082756'; + name = 'CreateAgentEntity1622621082756'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "agent" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "token" character varying NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "connectionId" uuid, CONSTRAINT "REL_5fa2f66b3adc27993e59ce043e" UNIQUE ("connectionId"), CONSTRAINT "PK_1000e989398c5d4ed585cf9a46f" PRIMARY KEY ("id"))`); - await queryRunner.query(`ALTER TABLE "agent" ADD CONSTRAINT "FK_5fa2f66b3adc27993e59ce043e5" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "agent" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "token" character varying NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "updatedAt" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "connectionId" uuid, CONSTRAINT "REL_5fa2f66b3adc27993e59ce043e" UNIQUE ("connectionId"), CONSTRAINT "PK_1000e989398c5d4ed585cf9a46f" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "agent" ADD CONSTRAINT "FK_5fa2f66b3adc27993e59ce043e5" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "agent" DROP CONSTRAINT "FK_5fa2f66b3adc27993e59ce043e5"`); - await queryRunner.query(`DROP TABLE "agent"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "agent" DROP CONSTRAINT "FK_5fa2f66b3adc27993e59ce043e5"`); + await queryRunner.query(`DROP TABLE "agent"`); + } } diff --git a/backend/src/migrations/1622621425033-SetDefaultNullInConnectionCredentialsProperties.ts b/backend/src/migrations/1622621425033-SetDefaultNullInConnectionCredentialsProperties.ts index ee1939cf2..9c636021d 100644 --- a/backend/src/migrations/1622621425033-SetDefaultNullInConnectionCredentialsProperties.ts +++ b/backend/src/migrations/1622621425033-SetDefaultNullInConnectionCredentialsProperties.ts @@ -1,50 +1,49 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class SetDefaultNullInConnectionCredentialsProperties1622621425033 implements MigrationInterface { - name = 'SetDefaultNullInConnectionCredentialsProperties1622621425033'; + name = 'SetDefaultNullInConnectionCredentialsProperties1622621425033'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "type" DROP NOT NULL`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "type" SET DEFAULT null`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "host" DROP NOT NULL`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "host" SET DEFAULT null`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "port" DROP NOT NULL`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "port" SET DEFAULT null`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "username" DROP NOT NULL`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "username" SET DEFAULT null`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "password" DROP NOT NULL`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "password" SET DEFAULT null`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "database" DROP NOT NULL`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "database" SET DEFAULT null`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "schema" SET DEFAULT null`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sid" SET DEFAULT null`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "privateSSHKey" SET DEFAULT null`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sshHost" SET DEFAULT null`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sshPort" SET DEFAULT null`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sshUsername" SET DEFAULT null`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "cert" SET DEFAULT null`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "cert" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sshUsername" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sshPort" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sshHost" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "privateSSHKey" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sid" SET DEFAULT NULL`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "schema" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "database" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "database" SET NOT NULL`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "password" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "password" SET NOT NULL`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "username" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "username" SET NOT NULL`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "port" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "port" SET NOT NULL`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "host" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "host" SET NOT NULL`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "type" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "type" SET NOT NULL`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "type" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "type" SET DEFAULT null`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "host" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "host" SET DEFAULT null`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "port" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "port" SET DEFAULT null`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "username" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "username" SET DEFAULT null`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "password" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "password" SET DEFAULT null`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "database" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "database" SET DEFAULT null`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "schema" SET DEFAULT null`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sid" SET DEFAULT null`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "privateSSHKey" SET DEFAULT null`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sshHost" SET DEFAULT null`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sshPort" SET DEFAULT null`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sshUsername" SET DEFAULT null`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "cert" SET DEFAULT null`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "cert" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sshUsername" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sshPort" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sshHost" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "privateSSHKey" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sid" SET DEFAULT NULL`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "schema" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "database" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "database" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "password" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "password" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "username" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "username" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "port" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "port" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "host" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "host" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "type" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "type" SET NOT NULL`); + } } diff --git a/backend/src/migrations/1623248308739-SetDefaultWidgetTypeAsNull.ts b/backend/src/migrations/1623248308739-SetDefaultWidgetTypeAsNull.ts index faccde80c..98c0397fd 100644 --- a/backend/src/migrations/1623248308739-SetDefaultWidgetTypeAsNull.ts +++ b/backend/src/migrations/1623248308739-SetDefaultWidgetTypeAsNull.ts @@ -1,16 +1,15 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class SetDefaultWidgetTypeAsNull1623248308739 implements MigrationInterface { - name = 'SetDefaultWidgetTypeAsNull1623248308739'; + name = 'SetDefaultWidgetTypeAsNull1623248308739'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_widget" ALTER COLUMN "widget_type" DROP NOT NULL`); - await queryRunner.query(`ALTER TABLE "table_widget" ALTER COLUMN "widget_type" SET DEFAULT null`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_widget" ALTER COLUMN "widget_type" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "table_widget" ALTER COLUMN "widget_type" SET NOT NULL`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_widget" ALTER COLUMN "widget_type" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "table_widget" ALTER COLUMN "widget_type" SET DEFAULT null`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_widget" ALTER COLUMN "widget_type" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "table_widget" ALTER COLUMN "widget_type" SET NOT NULL`); + } } diff --git a/backend/src/migrations/1623411474281-ChangeWidgetParamsTypeToJson.ts b/backend/src/migrations/1623411474281-ChangeWidgetParamsTypeToJson.ts index 230feba3e..c2b8d606c 100644 --- a/backend/src/migrations/1623411474281-ChangeWidgetParamsTypeToJson.ts +++ b/backend/src/migrations/1623411474281-ChangeWidgetParamsTypeToJson.ts @@ -1,16 +1,15 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class ChangeWidgetParamsTypeToJson1623411474281 implements MigrationInterface { - name = 'ChangeWidgetParamsTypeToJson1623411474281'; + name = 'ChangeWidgetParamsTypeToJson1623411474281'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_widget" DROP COLUMN "widget_params"`); - await queryRunner.query(`ALTER TABLE "table_widget" ADD "widget_params" json DEFAULT null`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_widget" DROP COLUMN "widget_params"`); - await queryRunner.query(`ALTER TABLE "table_widget" ADD "widget_params" character varying array`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_widget" DROP COLUMN "widget_params"`); + await queryRunner.query(`ALTER TABLE "table_widget" ADD "widget_params" json DEFAULT null`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_widget" DROP COLUMN "widget_params"`); + await queryRunner.query(`ALTER TABLE "table_widget" ADD "widget_params" character varying array`); + } } diff --git a/backend/src/migrations/1623745920707-AddAgentIdInConnectionEntity.ts b/backend/src/migrations/1623745920707-AddAgentIdInConnectionEntity.ts index cc918cba2..382cc1055 100644 --- a/backend/src/migrations/1623745920707-AddAgentIdInConnectionEntity.ts +++ b/backend/src/migrations/1623745920707-AddAgentIdInConnectionEntity.ts @@ -1,14 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddAgentIdInConnectionEntity1623745920707 implements MigrationInterface { - name = 'AddAgentIdInConnectionEntity1623745920707'; + name = 'AddAgentIdInConnectionEntity1623745920707'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableSettings" ADD "columns_view" character varying array DEFAULT null`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "columns_view"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableSettings" ADD "columns_view" character varying array DEFAULT null`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "columns_view"`); + } } diff --git a/backend/src/migrations/1624019569920-AddNewTableLogsEnumValues.ts b/backend/src/migrations/1624019569920-AddNewTableLogsEnumValues.ts index 6ceadc656..618bfdaf1 100644 --- a/backend/src/migrations/1624019569920-AddNewTableLogsEnumValues.ts +++ b/backend/src/migrations/1624019569920-AddNewTableLogsEnumValues.ts @@ -1,24 +1,33 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddNewTableLogsEnumValues1624019569920 implements MigrationInterface { - name = 'AddNewTableLogsEnumValues1624019569920' + name = 'AddNewTableLogsEnumValues1624019569920'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TYPE "public"."tableLogs_operationtype_enum" RENAME TO "tableLogs_operationtype_enum_old"`); - await queryRunner.query(`CREATE TYPE "tableLogs_operationtype_enum" AS ENUM('addRow', 'updateRow', 'deleteRow', 'unknown', 'rowReceived', 'rowsReceived')`); - await queryRunner.query(`ALTER TABLE "tableLogs" ALTER COLUMN "operationType" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "tableLogs" ALTER COLUMN "operationType" TYPE "tableLogs_operationtype_enum" USING "operationType"::"text"::"tableLogs_operationtype_enum"`); - await queryRunner.query(`ALTER TABLE "tableLogs" ALTER COLUMN "operationType" SET DEFAULT 'unknown'`); - await queryRunner.query(`DROP TYPE "tableLogs_operationtype_enum_old"`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TYPE "tableLogs_operationtype_enum_old" AS ENUM('addRow', 'updateRow', 'deleteRow', 'unknown')`); - await queryRunner.query(`ALTER TABLE "tableLogs" ALTER COLUMN "operationType" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "tableLogs" ALTER COLUMN "operationType" TYPE "tableLogs_operationtype_enum_old" USING "operationType"::"text"::"tableLogs_operationtype_enum_old"`); - await queryRunner.query(`ALTER TABLE "tableLogs" ALTER COLUMN "operationType" SET DEFAULT 'unknown'`); - await queryRunner.query(`DROP TYPE "tableLogs_operationtype_enum"`); - await queryRunner.query(`ALTER TYPE "tableLogs_operationtype_enum_old" RENAME TO "tableLogs_operationtype_enum"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TYPE "public"."tableLogs_operationtype_enum" RENAME TO "tableLogs_operationtype_enum_old"`, + ); + await queryRunner.query( + `CREATE TYPE "tableLogs_operationtype_enum" AS ENUM('addRow', 'updateRow', 'deleteRow', 'unknown', 'rowReceived', 'rowsReceived')`, + ); + await queryRunner.query(`ALTER TABLE "tableLogs" ALTER COLUMN "operationType" DROP DEFAULT`); + await queryRunner.query( + `ALTER TABLE "tableLogs" ALTER COLUMN "operationType" TYPE "tableLogs_operationtype_enum" USING "operationType"::"text"::"tableLogs_operationtype_enum"`, + ); + await queryRunner.query(`ALTER TABLE "tableLogs" ALTER COLUMN "operationType" SET DEFAULT 'unknown'`); + await queryRunner.query(`DROP TYPE "tableLogs_operationtype_enum_old"`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TYPE "tableLogs_operationtype_enum_old" AS ENUM('addRow', 'updateRow', 'deleteRow', 'unknown')`, + ); + await queryRunner.query(`ALTER TABLE "tableLogs" ALTER COLUMN "operationType" DROP DEFAULT`); + await queryRunner.query( + `ALTER TABLE "tableLogs" ALTER COLUMN "operationType" TYPE "tableLogs_operationtype_enum_old" USING "operationType"::"text"::"tableLogs_operationtype_enum_old"`, + ); + await queryRunner.query(`ALTER TABLE "tableLogs" ALTER COLUMN "operationType" SET DEFAULT 'unknown'`); + await queryRunner.query(`DROP TYPE "tableLogs_operationtype_enum"`); + await queryRunner.query(`ALTER TYPE "tableLogs_operationtype_enum_old" RENAME TO "tableLogs_operationtype_enum"`); + } } diff --git a/backend/src/migrations/1624962711767-AddIsTestConnectionPropertyInConnectionEntity.ts b/backend/src/migrations/1624962711767-AddIsTestConnectionPropertyInConnectionEntity.ts index af25e0a0c..e6a3532c0 100644 --- a/backend/src/migrations/1624962711767-AddIsTestConnectionPropertyInConnectionEntity.ts +++ b/backend/src/migrations/1624962711767-AddIsTestConnectionPropertyInConnectionEntity.ts @@ -1,14 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddIsTestConnectionPropertyInConnectionEntity1624962711767 implements MigrationInterface { - name = 'AddIsTestConnectionPropertyInConnectionEntity1624962711767'; + name = 'AddIsTestConnectionPropertyInConnectionEntity1624962711767'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" ADD "isTestConnection" boolean NOT NULL DEFAULT false`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "isTestConnection"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" ADD "isTestConnection" boolean NOT NULL DEFAULT false`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "isTestConnection"`); + } } diff --git a/backend/src/migrations/1625830829226-AddIdentityColumnInTableSettingsEntity.ts b/backend/src/migrations/1625830829226-AddIdentityColumnInTableSettingsEntity.ts index 5f197d24e..1aa6618f8 100644 --- a/backend/src/migrations/1625830829226-AddIdentityColumnInTableSettingsEntity.ts +++ b/backend/src/migrations/1625830829226-AddIdentityColumnInTableSettingsEntity.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddIdentityColumnInTableSettingsEntity1625830829226 implements MigrationInterface { - name = 'AddIdentityColumnInTableSettingsEntity1625830829226'; + name = 'AddIdentityColumnInTableSettingsEntity1625830829226'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableSettings" ADD "identity_column" character varying DEFAULT null`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableSettings" ADD "identity_column" character varying DEFAULT null`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "identity_column"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "identity_column"`); + } } diff --git a/backend/src/migrations/1630412519357-AddStripeIdInUserEntity.ts b/backend/src/migrations/1630412519357-AddStripeIdInUserEntity.ts index e38591e07..a29225e99 100644 --- a/backend/src/migrations/1630412519357-AddStripeIdInUserEntity.ts +++ b/backend/src/migrations/1630412519357-AddStripeIdInUserEntity.ts @@ -1,16 +1,15 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddStripeIdInUserEntity1630412519357 implements MigrationInterface { - name = 'AddStripeIdInUserEntity1630412519357'; + name = 'AddStripeIdInUserEntity1630412519357'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" ADD "stripeId" character varying DEFAULT null`); - } + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "stripeId"`); - } - + } } diff --git a/backend/src/migrations/1631794218888-AddWidgetOptionsInTableWidgetEntity.ts b/backend/src/migrations/1631794218888-AddWidgetOptionsInTableWidgetEntity.ts index 5b330986a..1064b89c9 100644 --- a/backend/src/migrations/1631794218888-AddWidgetOptionsInTableWidgetEntity.ts +++ b/backend/src/migrations/1631794218888-AddWidgetOptionsInTableWidgetEntity.ts @@ -1,15 +1,14 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddWidgetOptionsInTableWidgetEntity1631794218888 implements MigrationInterface { - name = 'AddWidgetOptionsInTableWidgetEntity1631794218888'; + name = 'AddWidgetOptionsInTableWidgetEntity1631794218888'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_widget" + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_widget" ADD "widget_options" json DEFAULT null`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_widget" DROP COLUMN "widget_options"`); - } + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_widget" DROP COLUMN "widget_options"`); + } } diff --git a/backend/src/migrations/1632485867215-AddCascadeOptionsIntoGroupEntity.ts b/backend/src/migrations/1632485867215-AddCascadeOptionsIntoGroupEntity.ts index 0cea4e2cf..4fa04b745 100644 --- a/backend/src/migrations/1632485867215-AddCascadeOptionsIntoGroupEntity.ts +++ b/backend/src/migrations/1632485867215-AddCascadeOptionsIntoGroupEntity.ts @@ -1,73 +1,47 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; -export class AddCascadeOptionsGroupEntity1632485867215 - implements MigrationInterface -{ - name = 'AddCascadeOptionsIntoUserAndPermissionsEntities1632485867215'; +export class AddCascadeOptionsGroupEntity1632485867215 implements MigrationInterface { + name = 'AddCascadeOptionsIntoUserAndPermissionsEntities1632485867215'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `ALTER TABLE "public"."user_groups_group" DROP CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462"`, - ); - await queryRunner.query( - `ALTER TABLE "public"."permission_groups_group" DROP CONSTRAINT "FK_0dd43db7f5e646262978c3ad0aa"`, - ); - await queryRunner.query( - `ALTER TABLE "public"."user" ALTER COLUMN "createdAt" SET DEFAULT now()`, - ); - await queryRunner.query( - `ALTER TABLE "public"."tableLogs" ALTER COLUMN "createdAt" SET DEFAULT now()`, - ); - await queryRunner.query( - `ALTER TABLE "public"."connection" ALTER COLUMN "createdAt" SET DEFAULT now()`, - ); - await queryRunner.query( - `ALTER TABLE "public"."connection" ALTER COLUMN "updatedAt" SET DEFAULT now()`, - ); - await queryRunner.query( - `ALTER TABLE "public"."agent" ALTER COLUMN "createdAt" SET DEFAULT now()`, - ); - await queryRunner.query( - `ALTER TABLE "public"."agent" ALTER COLUMN "updatedAt" SET DEFAULT now()`, - ); - await queryRunner.query( - `ALTER TABLE "public"."user_groups_group" ADD CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE`, - ); - await queryRunner.query( - `ALTER TABLE "public"."permission_groups_group" ADD CONSTRAINT "FK_0dd43db7f5e646262978c3ad0aa" FOREIGN KEY ("permissionId") REFERENCES "permission"("id") ON DELETE CASCADE ON UPDATE CASCADE`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "public"."user_groups_group" DROP CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462"`, + ); + await queryRunner.query( + `ALTER TABLE "public"."permission_groups_group" DROP CONSTRAINT "FK_0dd43db7f5e646262978c3ad0aa"`, + ); + await queryRunner.query(`ALTER TABLE "public"."user" ALTER COLUMN "createdAt" SET DEFAULT now()`); + await queryRunner.query(`ALTER TABLE "public"."tableLogs" ALTER COLUMN "createdAt" SET DEFAULT now()`); + await queryRunner.query(`ALTER TABLE "public"."connection" ALTER COLUMN "createdAt" SET DEFAULT now()`); + await queryRunner.query(`ALTER TABLE "public"."connection" ALTER COLUMN "updatedAt" SET DEFAULT now()`); + await queryRunner.query(`ALTER TABLE "public"."agent" ALTER COLUMN "createdAt" SET DEFAULT now()`); + await queryRunner.query(`ALTER TABLE "public"."agent" ALTER COLUMN "updatedAt" SET DEFAULT now()`); + await queryRunner.query( + `ALTER TABLE "public"."user_groups_group" ADD CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE`, + ); + await queryRunner.query( + `ALTER TABLE "public"."permission_groups_group" ADD CONSTRAINT "FK_0dd43db7f5e646262978c3ad0aa" FOREIGN KEY ("permissionId") REFERENCES "permission"("id") ON DELETE CASCADE ON UPDATE CASCADE`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `ALTER TABLE "public"."permission_groups_group" DROP CONSTRAINT "FK_0dd43db7f5e646262978c3ad0aa"`, - ); - await queryRunner.query( - `ALTER TABLE "public"."user_groups_group" DROP CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462"`, - ); - await queryRunner.query( - `ALTER TABLE "public"."agent" ALTER COLUMN "updatedAt" SET DEFAULT CURRENT_TIMESTAMP`, - ); - await queryRunner.query( - `ALTER TABLE "public"."agent" ALTER COLUMN "createdAt" SET DEFAULT CURRENT_TIMESTAMP`, - ); - await queryRunner.query( - `ALTER TABLE "public"."connection" ALTER COLUMN "updatedAt" SET DEFAULT CURRENT_TIMESTAMP`, - ); - await queryRunner.query( - `ALTER TABLE "public"."connection" ALTER COLUMN "createdAt" SET DEFAULT CURRENT_TIMESTAMP`, - ); - await queryRunner.query( - `ALTER TABLE "public"."tableLogs" ALTER COLUMN "createdAt" SET DEFAULT CURRENT_TIMESTAMP`, - ); - await queryRunner.query( - `ALTER TABLE "public"."user" ALTER COLUMN "createdAt" SET DEFAULT CURRENT_TIMESTAMP`, - ); - await queryRunner.query( - `ALTER TABLE "public"."permission_groups_group" ADD CONSTRAINT "FK_0dd43db7f5e646262978c3ad0aa" FOREIGN KEY ("permissionId") REFERENCES "permission"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "public"."user_groups_group" ADD CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "public"."permission_groups_group" DROP CONSTRAINT "FK_0dd43db7f5e646262978c3ad0aa"`, + ); + await queryRunner.query( + `ALTER TABLE "public"."user_groups_group" DROP CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462"`, + ); + await queryRunner.query(`ALTER TABLE "public"."agent" ALTER COLUMN "updatedAt" SET DEFAULT CURRENT_TIMESTAMP`); + await queryRunner.query(`ALTER TABLE "public"."agent" ALTER COLUMN "createdAt" SET DEFAULT CURRENT_TIMESTAMP`); + await queryRunner.query(`ALTER TABLE "public"."connection" ALTER COLUMN "updatedAt" SET DEFAULT CURRENT_TIMESTAMP`); + await queryRunner.query(`ALTER TABLE "public"."connection" ALTER COLUMN "createdAt" SET DEFAULT CURRENT_TIMESTAMP`); + await queryRunner.query(`ALTER TABLE "public"."tableLogs" ALTER COLUMN "createdAt" SET DEFAULT CURRENT_TIMESTAMP`); + await queryRunner.query(`ALTER TABLE "public"."user" ALTER COLUMN "createdAt" SET DEFAULT CURRENT_TIMESTAMP`); + await queryRunner.query( + `ALTER TABLE "public"."permission_groups_group" ADD CONSTRAINT "FK_0dd43db7f5e646262978c3ad0aa" FOREIGN KEY ("permissionId") REFERENCES "permission"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "public"."user_groups_group" ADD CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } } diff --git a/backend/src/migrations/1633691030155-AddConnectionPropertiesEntity.ts b/backend/src/migrations/1633691030155-AddConnectionPropertiesEntity.ts index cbbca35ff..457c742f7 100644 --- a/backend/src/migrations/1633691030155-AddConnectionPropertiesEntity.ts +++ b/backend/src/migrations/1633691030155-AddConnectionPropertiesEntity.ts @@ -1,11 +1,11 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddConnectionPropertiesEntity1633691030155 implements MigrationInterface { - name = 'AddConnectionPropertiesEntity1633691030155'; + name = 'AddConnectionPropertiesEntity1633691030155'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TABLE "connectionProperties" + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "connectionProperties" ( "id" uuid NOT NULL DEFAULT uuid_generate_v4(), "hidden_tables" character varying array, @@ -13,15 +13,15 @@ export class AddConnectionPropertiesEntity1633691030155 implements MigrationInte CONSTRAINT "REL_4c4090f071716a2333a2d5c52c" UNIQUE ("connectionId"), CONSTRAINT "PK_bbb7a755c1bfdcacd2e59622f57" PRIMARY KEY ("id") )`, - ); - await queryRunner.query( - `ALTER TABLE "connectionProperties" + ); + await queryRunner.query( + `ALTER TABLE "connectionProperties" ADD CONSTRAINT "FK_4c4090f071716a2333a2d5c52ca" FOREIGN KEY ("connectionId") REFERENCES "connection" ("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connectionProperties" DROP CONSTRAINT "FK_4c4090f071716a2333a2d5c52ca"`); - await queryRunner.query(`DROP TABLE "connectionProperties"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connectionProperties" DROP CONSTRAINT "FK_4c4090f071716a2333a2d5c52ca"`); + await queryRunner.query(`DROP TABLE "connectionProperties"`); + } } diff --git a/backend/src/migrations/1634730018905-AddAzureEncryptionPropertyIntoConnectionEntity.ts b/backend/src/migrations/1634730018905-AddAzureEncryptionPropertyIntoConnectionEntity.ts index e36310d41..917eb29c3 100644 --- a/backend/src/migrations/1634730018905-AddAzureEncryptionPropertyIntoConnectionEntity.ts +++ b/backend/src/migrations/1634730018905-AddAzureEncryptionPropertyIntoConnectionEntity.ts @@ -1,14 +1,14 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddAzureEncryptionPropertyIntoConnectionEntity1634730018905 implements MigrationInterface { - name = 'AddAzureEncryptionPropertyIntoConnectionEntity1634730018905'; + name = 'AddAzureEncryptionPropertyIntoConnectionEntity1634730018905'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" ADD "azure_encryption" boolean NOT NULL DEFAULT false`); - } + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "azure_encryption"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "azure_encryption"`); + } } diff --git a/backend/src/migrations/1639134878827-AddUserActionEntity.ts b/backend/src/migrations/1639134878827-AddUserActionEntity.ts index 3bdf0f5c7..deedadc3f 100644 --- a/backend/src/migrations/1639134878827-AddUserActionEntity.ts +++ b/backend/src/migrations/1639134878827-AddUserActionEntity.ts @@ -1,19 +1,19 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddUserActionEntity1639134878827 implements MigrationInterface { - name = 'AddUserActionEntity1639134878827'; + name = 'AddUserActionEntity1639134878827'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TABLE "user_action" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "message" character varying, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "mail_sent" boolean NOT NULL DEFAULT false, "userId" uuid, CONSTRAINT "REL_c025478b45e60017ed10c77f99" UNIQUE ("userId"), CONSTRAINT "PK_d035e078f4d722c689a98556169" PRIMARY KEY ("id"))`, - ); - await queryRunner.query( - `ALTER TABLE "user_action" ADD CONSTRAINT "FK_c025478b45e60017ed10c77f99c" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "user_action" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "message" character varying, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "mail_sent" boolean NOT NULL DEFAULT false, "userId" uuid, CONSTRAINT "REL_c025478b45e60017ed10c77f99" UNIQUE ("userId"), CONSTRAINT "PK_d035e078f4d722c689a98556169" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "user_action" ADD CONSTRAINT "FK_c025478b45e60017ed10c77f99c" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_action" DROP CONSTRAINT "FK_c025478b45e60017ed10c77f99c"`); - await queryRunner.query(`DROP TABLE "user_action"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user_action" DROP CONSTRAINT "FK_c025478b45e60017ed10c77f99c"`); + await queryRunner.query(`DROP TABLE "user_action"`); + } } diff --git a/backend/src/migrations/1642167861680-AddEmailAndPasswordAndMakeIdAutogeneratedInUserEntity.ts b/backend/src/migrations/1642167861680-AddEmailAndPasswordAndMakeIdAutogeneratedInUserEntity.ts index fd23e7a31..0ce6fc71e 100644 --- a/backend/src/migrations/1642167861680-AddEmailAndPasswordAndMakeIdAutogeneratedInUserEntity.ts +++ b/backend/src/migrations/1642167861680-AddEmailAndPasswordAndMakeIdAutogeneratedInUserEntity.ts @@ -1,43 +1,43 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddEmailAndPasswordAndMakeIdAutogeneratedInUserEntity1642167861680 implements MigrationInterface { - name = 'AddEmailAndPasswordAndMakeIdAutogeneratedInUserEntity1642167861680'; + name = 'AddEmailAndPasswordAndMakeIdAutogeneratedInUserEntity1642167861680'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" ADD "email" character varying`); - await queryRunner.query(`ALTER TABLE "user" ADD "password" character varying`); - await queryRunner.query(`ALTER TABLE "user_groups_group" DROP CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462"`); - await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); - await queryRunner.query(`ALTER TABLE "user_action" DROP CONSTRAINT "FK_c025478b45e60017ed10c77f99c"`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sid" DROP DEFAULT`); - await queryRunner.query( - `ALTER TABLE "user_action" ADD CONSTRAINT "FK_c025478b45e60017ed10c77f99c" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "user_groups_group" ADD CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE`, - ); - await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "id" SET DEFAULT uuid_generate_v4()`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" ADD "email" character varying`); + await queryRunner.query(`ALTER TABLE "user" ADD "password" character varying`); + await queryRunner.query(`ALTER TABLE "user_groups_group" DROP CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462"`); + await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); + await queryRunner.query(`ALTER TABLE "user_action" DROP CONSTRAINT "FK_c025478b45e60017ed10c77f99c"`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sid" DROP DEFAULT`); + await queryRunner.query( + `ALTER TABLE "user_action" ADD CONSTRAINT "FK_c025478b45e60017ed10c77f99c" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "user_groups_group" ADD CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE`, + ); + await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "id" SET DEFAULT uuid_generate_v4()`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_groups_group" DROP CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462"`); - await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); - await queryRunner.query(`ALTER TABLE "user_action" DROP CONSTRAINT "FK_c025478b45e60017ed10c77f99c"`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sid" SET DEFAULT NULL`); - await queryRunner.query( - `ALTER TABLE "user_action" ADD CONSTRAINT "FK_c025478b45e60017ed10c77f99c" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "user_groups_group" ADD CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE`, - ); - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "password"`); - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "email"`); - await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "id" DROP DEFAULT`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user_groups_group" DROP CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462"`); + await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); + await queryRunner.query(`ALTER TABLE "user_action" DROP CONSTRAINT "FK_c025478b45e60017ed10c77f99c"`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "sid" SET DEFAULT NULL`); + await queryRunner.query( + `ALTER TABLE "user_action" ADD CONSTRAINT "FK_c025478b45e60017ed10c77f99c" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "user_groups_group" ADD CONSTRAINT "FK_84ff6a520aee2bf2512c01cf462" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE`, + ); + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "password"`); + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "email"`); + await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "id" DROP DEFAULT`); + } } diff --git a/backend/src/migrations/1642415909665-AddLogOutEntity.ts b/backend/src/migrations/1642415909665-AddLogOutEntity.ts index 831427d3c..fa28d835f 100644 --- a/backend/src/migrations/1642415909665-AddLogOutEntity.ts +++ b/backend/src/migrations/1642415909665-AddLogOutEntity.ts @@ -1,15 +1,15 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddLogOutEntity1642415909665 implements MigrationInterface { - name = 'AddLogOutEntity1642415909665'; + name = 'AddLogOutEntity1642415909665'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TABLE "logout" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "jwtToken" character varying, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "PK_3c94c20f1447defd40481d1aca3" PRIMARY KEY ("id"))`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "logout" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "jwtToken" character varying, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "PK_3c94c20f1447defd40481d1aca3" PRIMARY KEY ("id"))`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP TABLE "logout"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE "logout"`); + } } diff --git a/backend/src/migrations/1642775235703-AddEmailVerificationEntity.ts b/backend/src/migrations/1642775235703-AddEmailVerificationEntity.ts index d0e3e8ff2..5be80b288 100644 --- a/backend/src/migrations/1642775235703-AddEmailVerificationEntity.ts +++ b/backend/src/migrations/1642775235703-AddEmailVerificationEntity.ts @@ -1,10 +1,10 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddEmailVerificationEntity1642775235703 implements MigrationInterface { - name = 'AddEmailVerificationEntity1642775235703'; + name = 'AddEmailVerificationEntity1642775235703'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "email_verification" + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TABLE "email_verification" ( "id" uuid NOT NULL DEFAULT uuid_generate_v4(), "verification_string" character varying, @@ -12,12 +12,12 @@ export class AddEmailVerificationEntity1642775235703 implements MigrationInterfa CONSTRAINT "REL_95b3bd492c85e471cd5e72277b" UNIQUE ("userId"), CONSTRAINT "PK_b985a8362d9dac51e3d6120d40e" PRIMARY KEY ("id") )`); - await queryRunner.query(`ALTER TABLE "email_verification" + await queryRunner.query(`ALTER TABLE "email_verification" ADD CONSTRAINT "FK_95b3bd492c85e471cd5e72277be" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION`); - } + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "email_verification" DROP CONSTRAINT "FK_95b3bd492c85e471cd5e72277be"`); - await queryRunner.query(`DROP TABLE "email_verification"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "email_verification" DROP CONSTRAINT "FK_95b3bd492c85e471cd5e72277be"`); + await queryRunner.query(`DROP TABLE "email_verification"`); + } } diff --git a/backend/src/migrations/1643204398361-AddPasswordResetEntity.ts b/backend/src/migrations/1643204398361-AddPasswordResetEntity.ts index 84e17ae75..7e1a19c78 100644 --- a/backend/src/migrations/1643204398361-AddPasswordResetEntity.ts +++ b/backend/src/migrations/1643204398361-AddPasswordResetEntity.ts @@ -1,21 +1,21 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddPasswordResetEntity1643204398361 implements MigrationInterface { - name = 'AddPasswordResetEntity1643204398361'; + name = 'AddPasswordResetEntity1643204398361'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TABLE "password_reset" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "verification_string" character varying, "userId" uuid, CONSTRAINT "REL_05baebe80e9f8fab8207eda250" UNIQUE ("userId"), CONSTRAINT "PK_8515e60a2cc41584fa4784f52ce" PRIMARY KEY ("id"))`, - ); - await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "isActive" SET DEFAULT false`); - await queryRunner.query( - `ALTER TABLE "password_reset" ADD CONSTRAINT "FK_05baebe80e9f8fab8207eda250c" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "password_reset" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "verification_string" character varying, "userId" uuid, CONSTRAINT "REL_05baebe80e9f8fab8207eda250" UNIQUE ("userId"), CONSTRAINT "PK_8515e60a2cc41584fa4784f52ce" PRIMARY KEY ("id"))`, + ); + await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "isActive" SET DEFAULT false`); + await queryRunner.query( + `ALTER TABLE "password_reset" ADD CONSTRAINT "FK_05baebe80e9f8fab8207eda250c" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "password_reset" DROP CONSTRAINT "FK_05baebe80e9f8fab8207eda250c"`); - await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "isActive" SET DEFAULT true`); - await queryRunner.query(`DROP TABLE "password_reset"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "password_reset" DROP CONSTRAINT "FK_05baebe80e9f8fab8207eda250c"`); + await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "isActive" SET DEFAULT true`); + await queryRunner.query(`DROP TABLE "password_reset"`); + } } diff --git a/backend/src/migrations/1643279671150-AddEmailChangeEntity.ts b/backend/src/migrations/1643279671150-AddEmailChangeEntity.ts index 306c59f82..ab5c03317 100644 --- a/backend/src/migrations/1643279671150-AddEmailChangeEntity.ts +++ b/backend/src/migrations/1643279671150-AddEmailChangeEntity.ts @@ -1,19 +1,19 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddEmailChangeEntity1643279671150 implements MigrationInterface { - name = 'AddEmailChangeEntity1643279671150'; + name = 'AddEmailChangeEntity1643279671150'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TABLE "email_change" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "verification_string" character varying, "userId" uuid, CONSTRAINT "REL_60574205c2ff8ad4851c741de1" UNIQUE ("userId"), CONSTRAINT "PK_3c41013cfc6b716e1feeb3c1ee1" PRIMARY KEY ("id"))`, - ); - await queryRunner.query( - `ALTER TABLE "email_change" ADD CONSTRAINT "FK_60574205c2ff8ad4851c741de1a" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "email_change" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "verification_string" character varying, "userId" uuid, CONSTRAINT "REL_60574205c2ff8ad4851c741de1" UNIQUE ("userId"), CONSTRAINT "PK_3c41013cfc6b716e1feeb3c1ee1" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "email_change" ADD CONSTRAINT "FK_60574205c2ff8ad4851c741de1a" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "email_change" DROP CONSTRAINT "FK_60574205c2ff8ad4851c741de1a"`); - await queryRunner.query(`DROP TABLE "email_change"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "email_change" DROP CONSTRAINT "FK_60574205c2ff8ad4851c741de1a"`); + await queryRunner.query(`DROP TABLE "email_change"`); + } } diff --git a/backend/src/migrations/1643631836210-AddUserInvitationEntity.ts b/backend/src/migrations/1643631836210-AddUserInvitationEntity.ts index 2af855bc9..8b8ba12d0 100644 --- a/backend/src/migrations/1643631836210-AddUserInvitationEntity.ts +++ b/backend/src/migrations/1643631836210-AddUserInvitationEntity.ts @@ -1,19 +1,19 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddUserInvitationEntity1643631836210 implements MigrationInterface { - name = 'AddUserInvitationEntity1643631836210'; + name = 'AddUserInvitationEntity1643631836210'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TABLE "user_invitation" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "verification_string" character varying, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "userId" uuid, CONSTRAINT "REL_494861800ebf740c1cf9f110e5" UNIQUE ("userId"), CONSTRAINT "PK_41026b90b70299ac5dc0183351a" PRIMARY KEY ("id"))`, - ); - await queryRunner.query( - `ALTER TABLE "user_invitation" ADD CONSTRAINT "FK_494861800ebf740c1cf9f110e5e" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "user_invitation" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "verification_string" character varying, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "userId" uuid, CONSTRAINT "REL_494861800ebf740c1cf9f110e5" UNIQUE ("userId"), CONSTRAINT "PK_41026b90b70299ac5dc0183351a" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "user_invitation" ADD CONSTRAINT "FK_494861800ebf740c1cf9f110e5e" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_invitation" DROP CONSTRAINT "FK_494861800ebf740c1cf9f110e5e"`); - await queryRunner.query(`DROP TABLE "user_invitation"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user_invitation" DROP CONSTRAINT "FK_494861800ebf740c1cf9f110e5e"`); + await queryRunner.query(`DROP TABLE "user_invitation"`); + } } diff --git a/backend/src/migrations/1647981342982-AddCascadeOptionForUserEntityInConnectionAndEmailVerificationEntities.ts b/backend/src/migrations/1647981342982-AddCascadeOptionForUserEntityInConnectionAndEmailVerificationEntities.ts index 4724fc9b7..7e79349e9 100644 --- a/backend/src/migrations/1647981342982-AddCascadeOptionForUserEntityInConnectionAndEmailVerificationEntities.ts +++ b/backend/src/migrations/1647981342982-AddCascadeOptionForUserEntityInConnectionAndEmailVerificationEntities.ts @@ -1,29 +1,29 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddCascadeOptionForUserEntityInConnectionAndEmailVerificationEntities1647981342982 - implements MigrationInterface + implements MigrationInterface { - name = 'AddCascadeOptionForUserEntityInConnectionAndEmailVerificationEntities1647981342982'; + name = 'AddCascadeOptionForUserEntityInConnectionAndEmailVerificationEntities1647981342982'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "email_verification" DROP CONSTRAINT "FK_95b3bd492c85e471cd5e72277be"`); - await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); - await queryRunner.query( - `ALTER TABLE "email_verification" ADD CONSTRAINT "FK_95b3bd492c85e471cd5e72277be" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "email_verification" DROP CONSTRAINT "FK_95b3bd492c85e471cd5e72277be"`); + await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); + await queryRunner.query( + `ALTER TABLE "email_verification" ADD CONSTRAINT "FK_95b3bd492c85e471cd5e72277be" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); - await queryRunner.query(`ALTER TABLE "email_verification" DROP CONSTRAINT "FK_95b3bd492c85e471cd5e72277be"`); - await queryRunner.query( - `ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "email_verification" ADD CONSTRAINT "FK_95b3bd492c85e471cd5e72277be" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); + await queryRunner.query(`ALTER TABLE "email_verification" DROP CONSTRAINT "FK_95b3bd492c85e471cd5e72277be"`); + await queryRunner.query( + `ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "email_verification" ADD CONSTRAINT "FK_95b3bd492c85e471cd5e72277be" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + } } diff --git a/backend/src/migrations/1649081443218-AddCascadeOptionsPasswordResetEmailChangeUserActionEntities.ts b/backend/src/migrations/1649081443218-AddCascadeOptionsPasswordResetEmailChangeUserActionEntities.ts index d58814a9b..eeeb492ba 100644 --- a/backend/src/migrations/1649081443218-AddCascadeOptionsPasswordResetEmailChangeUserActionEntities.ts +++ b/backend/src/migrations/1649081443218-AddCascadeOptionsPasswordResetEmailChangeUserActionEntities.ts @@ -1,43 +1,43 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddCascadeOptionsPasswordResetEmailChangeUserActionEntities1649081443218 implements MigrationInterface { - name = 'AddCascadeOptionsPasswordResetEmailChangeUserActionEntities1649081443218'; + name = 'AddCascadeOptionsPasswordResetEmailChangeUserActionEntities1649081443218'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_action" DROP CONSTRAINT "FK_c025478b45e60017ed10c77f99c"`); - await queryRunner.query(`ALTER TABLE "password_reset" DROP CONSTRAINT "FK_05baebe80e9f8fab8207eda250c"`); - await queryRunner.query(`ALTER TABLE "email_change" DROP CONSTRAINT "FK_60574205c2ff8ad4851c741de1a"`); - await queryRunner.query(`ALTER TABLE "user_invitation" DROP CONSTRAINT "FK_494861800ebf740c1cf9f110e5e"`); - await queryRunner.query( - `ALTER TABLE "user_action" ADD CONSTRAINT "FK_c025478b45e60017ed10c77f99c" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "password_reset" ADD CONSTRAINT "FK_05baebe80e9f8fab8207eda250c" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "email_change" ADD CONSTRAINT "FK_60574205c2ff8ad4851c741de1a" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "user_invitation" ADD CONSTRAINT "FK_494861800ebf740c1cf9f110e5e" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user_action" DROP CONSTRAINT "FK_c025478b45e60017ed10c77f99c"`); + await queryRunner.query(`ALTER TABLE "password_reset" DROP CONSTRAINT "FK_05baebe80e9f8fab8207eda250c"`); + await queryRunner.query(`ALTER TABLE "email_change" DROP CONSTRAINT "FK_60574205c2ff8ad4851c741de1a"`); + await queryRunner.query(`ALTER TABLE "user_invitation" DROP CONSTRAINT "FK_494861800ebf740c1cf9f110e5e"`); + await queryRunner.query( + `ALTER TABLE "user_action" ADD CONSTRAINT "FK_c025478b45e60017ed10c77f99c" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "password_reset" ADD CONSTRAINT "FK_05baebe80e9f8fab8207eda250c" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "email_change" ADD CONSTRAINT "FK_60574205c2ff8ad4851c741de1a" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "user_invitation" ADD CONSTRAINT "FK_494861800ebf740c1cf9f110e5e" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_invitation" DROP CONSTRAINT "FK_494861800ebf740c1cf9f110e5e"`); - await queryRunner.query(`ALTER TABLE "email_change" DROP CONSTRAINT "FK_60574205c2ff8ad4851c741de1a"`); - await queryRunner.query(`ALTER TABLE "password_reset" DROP CONSTRAINT "FK_05baebe80e9f8fab8207eda250c"`); - await queryRunner.query(`ALTER TABLE "user_action" DROP CONSTRAINT "FK_c025478b45e60017ed10c77f99c"`); - await queryRunner.query( - `ALTER TABLE "user_invitation" ADD CONSTRAINT "FK_494861800ebf740c1cf9f110e5e" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "email_change" ADD CONSTRAINT "FK_60574205c2ff8ad4851c741de1a" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "password_reset" ADD CONSTRAINT "FK_05baebe80e9f8fab8207eda250c" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "user_action" ADD CONSTRAINT "FK_c025478b45e60017ed10c77f99c" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user_invitation" DROP CONSTRAINT "FK_494861800ebf740c1cf9f110e5e"`); + await queryRunner.query(`ALTER TABLE "email_change" DROP CONSTRAINT "FK_60574205c2ff8ad4851c741de1a"`); + await queryRunner.query(`ALTER TABLE "password_reset" DROP CONSTRAINT "FK_05baebe80e9f8fab8207eda250c"`); + await queryRunner.query(`ALTER TABLE "user_action" DROP CONSTRAINT "FK_c025478b45e60017ed10c77f99c"`); + await queryRunner.query( + `ALTER TABLE "user_invitation" ADD CONSTRAINT "FK_494861800ebf740c1cf9f110e5e" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "email_change" ADD CONSTRAINT "FK_60574205c2ff8ad4851c741de1a" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "password_reset" ADD CONSTRAINT "FK_05baebe80e9f8fab8207eda250c" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "user_action" ADD CONSTRAINT "FK_c025478b45e60017ed10c77f99c" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + } } diff --git a/backend/src/migrations/1653562421593-AddJobsListEntity.ts b/backend/src/migrations/1653562421593-AddJobsListEntity.ts index 6ea1454a9..5d9a237d0 100644 --- a/backend/src/migrations/1653562421593-AddJobsListEntity.ts +++ b/backend/src/migrations/1653562421593-AddJobsListEntity.ts @@ -1,14 +1,15 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddJobsListEntity1653562421593 implements MigrationInterface { - name = 'AddJobsListEntity1653562421593' + name = 'AddJobsListEntity1653562421593'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "job_list" ("job_key" character varying(100) NOT NULL, CONSTRAINT "PK_d14e7f19b86450b1cafc689ca41" PRIMARY KEY ("job_key"))`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP TABLE "job_list"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "job_list" ("job_key" character varying(100) NOT NULL, CONSTRAINT "PK_d14e7f19b86450b1cafc689ca41" PRIMARY KEY ("job_key"))`, + ); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE "job_list"`); + } } diff --git a/backend/src/migrations/1658913681818-AddTableInfoEntity.ts b/backend/src/migrations/1658913681818-AddTableInfoEntity.ts index 8497dafe9..67bec5240 100644 --- a/backend/src/migrations/1658913681818-AddTableInfoEntity.ts +++ b/backend/src/migrations/1658913681818-AddTableInfoEntity.ts @@ -1,29 +1,29 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddTableInfoEntity1658913681818 implements MigrationInterface { - name = 'AddTableInfoEntity1658913681818'; + name = 'AddTableInfoEntity1658913681818'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TABLE "table_field_info" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "allow_null" boolean, "character_maximum_length" integer, "column_default" character varying, "column_name" character varying, "data_type" character varying, "data_type_params" character varying, "udt_name" character varying, "tableInfoId" uuid, CONSTRAINT "PK_88bed139d648523aad1df46d6ff" PRIMARY KEY ("id"))`, - ); - await queryRunner.query( - `CREATE TABLE "table_info" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "table_name" character varying NOT NULL, "connectionId" uuid, CONSTRAINT "PK_4dc62b1f8615f01359c4ebbc188" PRIMARY KEY ("id"))`, - ); - await queryRunner.query(`ALTER TABLE "connection" ADD "saved_table_info" integer NOT NULL DEFAULT 0`); - await queryRunner.query( - `ALTER TABLE "table_field_info" ADD CONSTRAINT "FK_e955c1750aa76b5691c5044d30c" FOREIGN KEY ("tableInfoId") REFERENCES "table_info"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "table_info" ADD CONSTRAINT "FK_0b9cf14b1a4c562a84eae8f70f2" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "table_field_info" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "allow_null" boolean, "character_maximum_length" integer, "column_default" character varying, "column_name" character varying, "data_type" character varying, "data_type_params" character varying, "udt_name" character varying, "tableInfoId" uuid, CONSTRAINT "PK_88bed139d648523aad1df46d6ff" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "table_info" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "table_name" character varying NOT NULL, "connectionId" uuid, CONSTRAINT "PK_4dc62b1f8615f01359c4ebbc188" PRIMARY KEY ("id"))`, + ); + await queryRunner.query(`ALTER TABLE "connection" ADD "saved_table_info" integer NOT NULL DEFAULT 0`); + await queryRunner.query( + `ALTER TABLE "table_field_info" ADD CONSTRAINT "FK_e955c1750aa76b5691c5044d30c" FOREIGN KEY ("tableInfoId") REFERENCES "table_info"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "table_info" ADD CONSTRAINT "FK_0b9cf14b1a4c562a84eae8f70f2" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_info" DROP CONSTRAINT "FK_0b9cf14b1a4c562a84eae8f70f2"`); - await queryRunner.query(`ALTER TABLE "table_field_info" DROP CONSTRAINT "FK_e955c1750aa76b5691c5044d30c"`); - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "saved_table_info"`); - await queryRunner.query(`DROP TABLE "table_info"`); - await queryRunner.query(`DROP TABLE "table_field_info"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_info" DROP CONSTRAINT "FK_0b9cf14b1a4c562a84eae8f70f2"`); + await queryRunner.query(`ALTER TABLE "table_field_info" DROP CONSTRAINT "FK_e955c1750aa76b5691c5044d30c"`); + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "saved_table_info"`); + await queryRunner.query(`DROP TABLE "table_info"`); + await queryRunner.query(`DROP TABLE "table_field_info"`); + } } diff --git a/backend/src/migrations/1661518838769-CharacterMaximumLengthTypeChangedToString.ts b/backend/src/migrations/1661518838769-CharacterMaximumLengthTypeChangedToString.ts index a45d2a304..c57c1b4e8 100644 --- a/backend/src/migrations/1661518838769-CharacterMaximumLengthTypeChangedToString.ts +++ b/backend/src/migrations/1661518838769-CharacterMaximumLengthTypeChangedToString.ts @@ -1,17 +1,17 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class CharacterMaximumLengthTypeChangedToString1661518838769 implements MigrationInterface { - name = 'CharacterMaximumLengthTypeChangedToString1661518838769'; + name = 'CharacterMaximumLengthTypeChangedToString1661518838769'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_field_info" DROP COLUMN "character_maximum_length"`); - await queryRunner.query(`ALTER TABLE "table_field_info" + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_field_info" DROP COLUMN "character_maximum_length"`); + await queryRunner.query(`ALTER TABLE "table_field_info" ADD "character_maximum_length" character varying`); - } + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_field_info" DROP COLUMN "character_maximum_length"`); - await queryRunner.query(`ALTER TABLE "table_field_info" + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_field_info" DROP COLUMN "character_maximum_length"`); + await queryRunner.query(`ALTER TABLE "table_field_info" ADD "character_maximum_length" integer`); - } + } } diff --git a/backend/src/migrations/1665573937087-AddTableActionEntity.ts b/backend/src/migrations/1665573937087-AddTableActionEntity.ts index 727ed953e..59e15d233 100644 --- a/backend/src/migrations/1665573937087-AddTableActionEntity.ts +++ b/backend/src/migrations/1665573937087-AddTableActionEntity.ts @@ -1,21 +1,21 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddTableActionEntity1665573937087 implements MigrationInterface { - name = 'AddTableActionEntity1665573937087'; + name = 'AddTableActionEntity1665573937087'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TYPE "public"."table_actions_type_enum" AS ENUM('single', 'multiple')`); - await queryRunner.query( - `CREATE TABLE "table_actions" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "title" character varying, "type" "public"."table_actions_type_enum" NOT NULL DEFAULT 'single', "url" character varying, "settingsId" uuid, CONSTRAINT "PK_56c3f0c6b43b21727d181744f5c" PRIMARY KEY ("id"))`, - ); - await queryRunner.query( - `ALTER TABLE "table_actions" ADD CONSTRAINT "FK_e6cbca5311c836511e42ff3477c" FOREIGN KEY ("settingsId") REFERENCES "tableSettings"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TYPE "public"."table_actions_type_enum" AS ENUM('single', 'multiple')`); + await queryRunner.query( + `CREATE TABLE "table_actions" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "title" character varying, "type" "public"."table_actions_type_enum" NOT NULL DEFAULT 'single', "url" character varying, "settingsId" uuid, CONSTRAINT "PK_56c3f0c6b43b21727d181744f5c" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "table_actions" ADD CONSTRAINT "FK_e6cbca5311c836511e42ff3477c" FOREIGN KEY ("settingsId") REFERENCES "tableSettings"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_actions" DROP CONSTRAINT "FK_e6cbca5311c836511e42ff3477c"`); - await queryRunner.query(`DROP TABLE "table_actions"`); - await queryRunner.query(`DROP TYPE "public"."table_actions_type_enum"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_actions" DROP CONSTRAINT "FK_e6cbca5311c836511e42ff3477c"`); + await queryRunner.query(`DROP TABLE "table_actions"`); + await queryRunner.query(`DROP TYPE "public"."table_actions_type_enum"`); + } } diff --git a/backend/src/migrations/1665738096916-AddSigningKeyInConnectionEntity.ts b/backend/src/migrations/1665738096916-AddSigningKeyInConnectionEntity.ts index 4af8c8c08..ee4640638 100644 --- a/backend/src/migrations/1665738096916-AddSigningKeyInConnectionEntity.ts +++ b/backend/src/migrations/1665738096916-AddSigningKeyInConnectionEntity.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddSigningKeyInConnectionEntity1665738096916 implements MigrationInterface { - name = 'AddSigningKeyInConnectionEntity1665738096916'; + name = 'AddSigningKeyInConnectionEntity1665738096916'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" ADD "signing_key" character varying`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" ADD "signing_key" character varying`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "signing_key"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "signing_key"`); + } } diff --git a/backend/src/migrations/1666959132601-AddCanDeleteUpdateAddOptionsInTableSettingsEntity.ts b/backend/src/migrations/1666959132601-AddCanDeleteUpdateAddOptionsInTableSettingsEntity.ts index 4987ff381..264a192f3 100644 --- a/backend/src/migrations/1666959132601-AddCanDeleteUpdateAddOptionsInTableSettingsEntity.ts +++ b/backend/src/migrations/1666959132601-AddCanDeleteUpdateAddOptionsInTableSettingsEntity.ts @@ -1,17 +1,17 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddCanDeleteUpdateAddOptionsInTableSettingsEntity1666959132601 implements MigrationInterface { - name = 'AddCanDeleteUpdateAddOptionsInTableSettingsEntity1666959132601'; + name = 'AddCanDeleteUpdateAddOptionsInTableSettingsEntity1666959132601'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableSettings" ADD "can_delete" boolean NOT NULL DEFAULT true`); - await queryRunner.query(`ALTER TABLE "tableSettings" ADD "can_update" boolean NOT NULL DEFAULT true`); - await queryRunner.query(`ALTER TABLE "tableSettings" ADD "can_add" boolean NOT NULL DEFAULT true`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableSettings" ADD "can_delete" boolean NOT NULL DEFAULT true`); + await queryRunner.query(`ALTER TABLE "tableSettings" ADD "can_update" boolean NOT NULL DEFAULT true`); + await queryRunner.query(`ALTER TABLE "tableSettings" ADD "can_add" boolean NOT NULL DEFAULT true`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "can_add"`); - await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "can_update"`); - await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "can_delete"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "can_add"`); + await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "can_update"`); + await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "can_delete"`); + } } diff --git a/backend/src/migrations/1667830553647-AddNamePropertyInUserEntity.ts b/backend/src/migrations/1667830553647-AddNamePropertyInUserEntity.ts index b55fee9cf..bc45d0c31 100644 --- a/backend/src/migrations/1667830553647-AddNamePropertyInUserEntity.ts +++ b/backend/src/migrations/1667830553647-AddNamePropertyInUserEntity.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddNamePropertyInUserEntity1667830553647 implements MigrationInterface { - name = 'AddNamePropertyInUserEntity1667830553647'; + name = 'AddNamePropertyInUserEntity1667830553647'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" ADD "name" character varying`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" ADD "name" character varying`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "name"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "name"`); + } } diff --git a/backend/src/migrations/1668705804535-AddIconFieldInTableActionEntity.ts b/backend/src/migrations/1668705804535-AddIconFieldInTableActionEntity.ts index 87ddd6567..fbbbf6263 100644 --- a/backend/src/migrations/1668705804535-AddIconFieldInTableActionEntity.ts +++ b/backend/src/migrations/1668705804535-AddIconFieldInTableActionEntity.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddIconFieldInTableActionEntity1668705804535 implements MigrationInterface { - name = 'AddIconFieldInTableActionEntity1668705804535'; + name = 'AddIconFieldInTableActionEntity1668705804535'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_actions" ADD "icon" character varying`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_actions" ADD "icon" character varying`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "icon"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "icon"`); + } } diff --git a/backend/src/migrations/1669212083676-AddOwnerIdFieldInUserInvitationEntity.ts b/backend/src/migrations/1669212083676-AddOwnerIdFieldInUserInvitationEntity.ts index 92642266d..3f67f0605 100644 --- a/backend/src/migrations/1669212083676-AddOwnerIdFieldInUserInvitationEntity.ts +++ b/backend/src/migrations/1669212083676-AddOwnerIdFieldInUserInvitationEntity.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddOwnerIdFieldInUserInvitationEntity1669212083676 implements MigrationInterface { - name = 'AddOwnerIdFieldInUserInvitationEntity1669212083676'; + name = 'AddOwnerIdFieldInUserInvitationEntity1669212083676'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_invitation" ADD "ownerId" character varying`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user_invitation" ADD "ownerId" character varying`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_invitation" DROP COLUMN "ownerId"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user_invitation" DROP COLUMN "ownerId"`); + } } diff --git a/backend/src/migrations/1669625339950-AddSensitiveFieldsInTableSettingsEntity.ts b/backend/src/migrations/1669625339950-AddSensitiveFieldsInTableSettingsEntity.ts index 897c68612..5c712c3a4 100644 --- a/backend/src/migrations/1669625339950-AddSensitiveFieldsInTableSettingsEntity.ts +++ b/backend/src/migrations/1669625339950-AddSensitiveFieldsInTableSettingsEntity.ts @@ -1,14 +1,13 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddSensitiveFieldsInTableSettingsEntity1669625339950 implements MigrationInterface { - name = 'AddSensitiveFieldsInTableSettingsEntity1669625339950' + name = 'AddSensitiveFieldsInTableSettingsEntity1669625339950'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableSettings" ADD "sensitive_fields" character varying array`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "sensitive_fields"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableSettings" ADD "sensitive_fields" character varying array`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "sensitive_fields"`); + } } diff --git a/backend/src/migrations/1670323988951-AddActionActivatedLogOperationType.ts b/backend/src/migrations/1670323988951-AddActionActivatedLogOperationType.ts index d6374997b..955305aa3 100644 --- a/backend/src/migrations/1670323988951-AddActionActivatedLogOperationType.ts +++ b/backend/src/migrations/1670323988951-AddActionActivatedLogOperationType.ts @@ -1,35 +1,35 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddActionActivatedLogOperationType1670323988951 implements MigrationInterface { - name = 'AddActionActivatedLogOperationType1670323988951'; + name = 'AddActionActivatedLogOperationType1670323988951'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `ALTER TYPE "public"."tableLogs_operationtype_enum" RENAME TO "tableLogs_operationtype_enum_old"`, - ); - await queryRunner.query( - `CREATE TYPE "public"."tableLogs_operationtype_enum" AS ENUM('addRow', 'updateRow', 'deleteRow', 'unknown', 'rowReceived', 'rowsReceived', 'actionActivated')`, - ); - await queryRunner.query(`ALTER TABLE "tableLogs" ALTER COLUMN "operationType" DROP DEFAULT`); - await queryRunner.query( - `ALTER TABLE "tableLogs" ALTER COLUMN "operationType" TYPE "public"."tableLogs_operationtype_enum" USING "operationType"::"text"::"public"."tableLogs_operationtype_enum"`, - ); - await queryRunner.query(`ALTER TABLE "tableLogs" ALTER COLUMN "operationType" SET DEFAULT 'unknown'`); - await queryRunner.query(`DROP TYPE "public"."tableLogs_operationtype_enum_old"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TYPE "public"."tableLogs_operationtype_enum" RENAME TO "tableLogs_operationtype_enum_old"`, + ); + await queryRunner.query( + `CREATE TYPE "public"."tableLogs_operationtype_enum" AS ENUM('addRow', 'updateRow', 'deleteRow', 'unknown', 'rowReceived', 'rowsReceived', 'actionActivated')`, + ); + await queryRunner.query(`ALTER TABLE "tableLogs" ALTER COLUMN "operationType" DROP DEFAULT`); + await queryRunner.query( + `ALTER TABLE "tableLogs" ALTER COLUMN "operationType" TYPE "public"."tableLogs_operationtype_enum" USING "operationType"::"text"::"public"."tableLogs_operationtype_enum"`, + ); + await queryRunner.query(`ALTER TABLE "tableLogs" ALTER COLUMN "operationType" SET DEFAULT 'unknown'`); + await queryRunner.query(`DROP TYPE "public"."tableLogs_operationtype_enum_old"`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TYPE "public"."tableLogs_operationtype_enum_old" AS ENUM('addRow', 'updateRow', 'deleteRow', 'unknown', 'rowReceived', 'rowsReceived')`, - ); - await queryRunner.query(`ALTER TABLE "tableLogs" ALTER COLUMN "operationType" DROP DEFAULT`); - await queryRunner.query( - `ALTER TABLE "tableLogs" ALTER COLUMN "operationType" TYPE "public"."tableLogs_operationtype_enum_old" USING "operationType"::"text"::"public"."tableLogs_operationtype_enum_old"`, - ); - await queryRunner.query(`ALTER TABLE "tableLogs" ALTER COLUMN "operationType" SET DEFAULT 'unknown'`); - await queryRunner.query(`DROP TYPE "public"."tableLogs_operationtype_enum"`); - await queryRunner.query( - `ALTER TYPE "public"."tableLogs_operationtype_enum_old" RENAME TO "tableLogs_operationtype_enum"`, - ); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TYPE "public"."tableLogs_operationtype_enum_old" AS ENUM('addRow', 'updateRow', 'deleteRow', 'unknown', 'rowReceived', 'rowsReceived')`, + ); + await queryRunner.query(`ALTER TABLE "tableLogs" ALTER COLUMN "operationType" DROP DEFAULT`); + await queryRunner.query( + `ALTER TABLE "tableLogs" ALTER COLUMN "operationType" TYPE "public"."tableLogs_operationtype_enum_old" USING "operationType"::"text"::"public"."tableLogs_operationtype_enum_old"`, + ); + await queryRunner.query(`ALTER TABLE "tableLogs" ALTER COLUMN "operationType" SET DEFAULT 'unknown'`); + await queryRunner.query(`DROP TYPE "public"."tableLogs_operationtype_enum"`); + await queryRunner.query( + `ALTER TYPE "public"."tableLogs_operationtype_enum_old" RENAME TO "tableLogs_operationtype_enum"`, + ); + } } diff --git a/backend/src/migrations/1671555413304-CascadeOptionChangedToNoActionInConnectionEntity.ts b/backend/src/migrations/1671555413304-CascadeOptionChangedToNoActionInConnectionEntity.ts index b3498c097..eb7f31cdd 100644 --- a/backend/src/migrations/1671555413304-CascadeOptionChangedToNoActionInConnectionEntity.ts +++ b/backend/src/migrations/1671555413304-CascadeOptionChangedToNoActionInConnectionEntity.ts @@ -1,16 +1,19 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class CascadeOptionChangedToNoActionInConnectionEntity1671555413304 implements MigrationInterface { - name = 'CascadeOptionChangedToNoActionInConnectionEntity1671555413304' + name = 'CascadeOptionChangedToNoActionInConnectionEntity1671555413304'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); - await queryRunner.query(`ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); - await queryRunner.query(`ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); + await queryRunner.query( + `ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); + await queryRunner.query( + `ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`, + ); + } } diff --git a/backend/src/migrations/1671701607316-SetOnDeleteCascadeInConnectionEntity.ts b/backend/src/migrations/1671701607316-SetOnDeleteCascadeInConnectionEntity.ts index 355991f97..376d3ddc7 100644 --- a/backend/src/migrations/1671701607316-SetOnDeleteCascadeInConnectionEntity.ts +++ b/backend/src/migrations/1671701607316-SetOnDeleteCascadeInConnectionEntity.ts @@ -1,16 +1,19 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class SetOnDeleteCascadeInConnectionEntity1671701607316 implements MigrationInterface { - name = 'SetOnDeleteCascadeInConnectionEntity1671701607316' + name = 'SetOnDeleteCascadeInConnectionEntity1671701607316'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); - await queryRunner.query(`ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); - await queryRunner.query(`ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); + await queryRunner.query( + `ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); + await queryRunner.query( + `ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + } } diff --git a/backend/src/migrations/1674568279297-AddPropertyRequireConfirmationInTableActionEntity.ts b/backend/src/migrations/1674568279297-AddPropertyRequireConfirmationInTableActionEntity.ts index 6901bb682..9a0addd2a 100644 --- a/backend/src/migrations/1674568279297-AddPropertyRequireConfirmationInTableActionEntity.ts +++ b/backend/src/migrations/1674568279297-AddPropertyRequireConfirmationInTableActionEntity.ts @@ -1,14 +1,13 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddPropertyRequireConfirmationInTableActionEntity1674568279297 implements MigrationInterface { - name = 'AddPropertyRequireConfirmationInTableActionEntity1674568279297' + name = 'AddPropertyRequireConfirmationInTableActionEntity1674568279297'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_actions" ADD "require_confirmation" boolean NOT NULL DEFAULT false`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "require_confirmation"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_actions" ADD "require_confirmation" boolean NOT NULL DEFAULT false`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "require_confirmation"`); + } } diff --git a/backend/src/migrations/1678180854454-AddLogoUrlColorsHostNameInConnectionProperties.ts b/backend/src/migrations/1678180854454-AddLogoUrlColorsHostNameInConnectionProperties.ts index 7be70af00..35c3c6b46 100644 --- a/backend/src/migrations/1678180854454-AddLogoUrlColorsHostNameInConnectionProperties.ts +++ b/backend/src/migrations/1678180854454-AddLogoUrlColorsHostNameInConnectionProperties.ts @@ -1,20 +1,19 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddLogoUrlColorsHostNameInConnectionProperties1678180854454 implements MigrationInterface { - name = 'AddLogoUrlColorsHostNameInConnectionProperties1678180854454' + name = 'AddLogoUrlColorsHostNameInConnectionProperties1678180854454'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "logo_url" character varying`); - await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "primary_color" character varying`); - await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "secondary_color" character varying`); - await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "hostname" character varying`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "hostname"`); - await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "secondary_color"`); - await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "primary_color"`); - await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "logo_url"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "logo_url" character varying`); + await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "primary_color" character varying`); + await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "secondary_color" character varying`); + await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "hostname" character varying`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "hostname"`); + await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "secondary_color"`); + await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "primary_color"`); + await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "logo_url"`); + } } diff --git a/backend/src/migrations/1678195304537-AddCompanyNamePropertyConnectionProperties.ts b/backend/src/migrations/1678195304537-AddCompanyNamePropertyConnectionProperties.ts index c5535d60d..3cb45ece9 100644 --- a/backend/src/migrations/1678195304537-AddCompanyNamePropertyConnectionProperties.ts +++ b/backend/src/migrations/1678195304537-AddCompanyNamePropertyConnectionProperties.ts @@ -1,14 +1,13 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddCompanyNamePropertyConnectionProperties1678195304537 implements MigrationInterface { - name = 'AddCompanyNamePropertyConnectionProperties1678195304537' + name = 'AddCompanyNamePropertyConnectionProperties1678195304537'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "company_name" character varying`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "company_name"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "company_name" character varying`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "company_name"`); + } } diff --git a/backend/src/migrations/1684929112779-AddTwoFactorInUserEntity.ts b/backend/src/migrations/1684929112779-AddTwoFactorInUserEntity.ts index e978075ea..80448dee9 100644 --- a/backend/src/migrations/1684929112779-AddTwoFactorInUserEntity.ts +++ b/backend/src/migrations/1684929112779-AddTwoFactorInUserEntity.ts @@ -1,15 +1,15 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddTwoFactorInUserEntity1684929112779 implements MigrationInterface { - name = 'AddTwoFactorInUserEntity1684929112779'; + name = 'AddTwoFactorInUserEntity1684929112779'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" ADD "isOTPEnabled" boolean NOT NULL DEFAULT false`); - await queryRunner.query(`ALTER TABLE "user" ADD "otpSecretKey" character varying`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" ADD "isOTPEnabled" boolean NOT NULL DEFAULT false`); + await queryRunner.query(`ALTER TABLE "user" ADD "otpSecretKey" character varying`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "otpSecretKey"`); - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "isOTPEnabled"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "otpSecretKey"`); + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "isOTPEnabled"`); + } } diff --git a/backend/src/migrations/1686131341609-AddIconPropertyInTableSettings.ts b/backend/src/migrations/1686131341609-AddIconPropertyInTableSettings.ts index 8d60e0ca3..1a9b75d65 100644 --- a/backend/src/migrations/1686131341609-AddIconPropertyInTableSettings.ts +++ b/backend/src/migrations/1686131341609-AddIconPropertyInTableSettings.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddIconPropertyInTableSettings1686131341609 implements MigrationInterface { - name = 'AddIconPropertyInTableSettings1686131341609'; + name = 'AddIconPropertyInTableSettings1686131341609'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableSettings" ADD "icon" character varying`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableSettings" ADD "icon" character varying`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "icon"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "icon"`); + } } diff --git a/backend/src/migrations/1688124324544-AddUserGithubAuthentificationEntity.ts b/backend/src/migrations/1688124324544-AddUserGithubAuthentificationEntity.ts index a8ab4c5b5..84b135682 100644 --- a/backend/src/migrations/1688124324544-AddUserGithubAuthentificationEntity.ts +++ b/backend/src/migrations/1688124324544-AddUserGithubAuthentificationEntity.ts @@ -1,19 +1,19 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddUserGithubAuthentificationEntity1688124324544 implements MigrationInterface { - name = 'AddUserGithubAuthentificationEntity1688124324544'; + name = 'AddUserGithubAuthentificationEntity1688124324544'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TABLE "github_user_identifier" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "gitHubId" integer NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "userId" uuid, CONSTRAINT "UQ_08cb07e43b5c13aba0d1c57fd45" UNIQUE ("gitHubId"), CONSTRAINT "REL_6458d9fad94d3972fcfdd1628b" UNIQUE ("userId"), CONSTRAINT "PK_2d0dd20c8d9c560de948be5f261" PRIMARY KEY ("id"))`, - ); - await queryRunner.query( - `ALTER TABLE "github_user_identifier" ADD CONSTRAINT "FK_6458d9fad94d3972fcfdd1628b0" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "github_user_identifier" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "gitHubId" integer NOT NULL, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "userId" uuid, CONSTRAINT "UQ_08cb07e43b5c13aba0d1c57fd45" UNIQUE ("gitHubId"), CONSTRAINT "REL_6458d9fad94d3972fcfdd1628b" UNIQUE ("userId"), CONSTRAINT "PK_2d0dd20c8d9c560de948be5f261" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "github_user_identifier" ADD CONSTRAINT "FK_6458d9fad94d3972fcfdd1628b0" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "github_user_identifier" DROP CONSTRAINT "FK_6458d9fad94d3972fcfdd1628b0"`); - await queryRunner.query(`DROP TABLE "github_user_identifier"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "github_user_identifier" DROP CONSTRAINT "FK_6458d9fad94d3972fcfdd1628b0"`); + await queryRunner.query(`DROP TABLE "github_user_identifier"`); + } } diff --git a/backend/src/migrations/1689694229370-AddCompanyIdsInUserEntity.ts b/backend/src/migrations/1689694229370-AddCompanyIdsInUserEntity.ts index cd86fe48c..c4db18e4c 100644 --- a/backend/src/migrations/1689694229370-AddCompanyIdsInUserEntity.ts +++ b/backend/src/migrations/1689694229370-AddCompanyIdsInUserEntity.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddCompanyIdsInUserEntity1689694229370 implements MigrationInterface { - name = 'AddCompanyIdsInUserEntity1689694229370'; + name = 'AddCompanyIdsInUserEntity1689694229370'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" ADD "companyIds" uuid array NOT NULL DEFAULT '{}'`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" ADD "companyIds" uuid array NOT NULL DEFAULT '{}'`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "companyIds"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "companyIds"`); + } } diff --git a/backend/src/migrations/1690297009826-AddCompanyInfoEntity.ts b/backend/src/migrations/1690297009826-AddCompanyInfoEntity.ts index 113c51b84..e96c5ab86 100644 --- a/backend/src/migrations/1690297009826-AddCompanyInfoEntity.ts +++ b/backend/src/migrations/1690297009826-AddCompanyInfoEntity.ts @@ -1,31 +1,31 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddCompanyInfoEntity1690297009826 implements MigrationInterface { - name = 'AddCompanyInfoEntity1690297009826'; + name = 'AddCompanyInfoEntity1690297009826'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" RENAME COLUMN "companyIds" TO "companyId"`); - await queryRunner.query( - `CREATE TABLE "company_info" ("id" uuid NOT NULL, CONSTRAINT "PK_88c3e323679d0747ffbb83f3f78" PRIMARY KEY ("id"))`, - ); - await queryRunner.query(`ALTER TABLE "connection" ADD "companyId" uuid`); - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "companyId"`); - await queryRunner.query(`ALTER TABLE "user" ADD "companyId" uuid`); - await queryRunner.query( - `ALTER TABLE "user" ADD CONSTRAINT "FK_86586021a26d1180b0968f98502" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "connection" ADD CONSTRAINT "FK_3c56723750fad39864878239cf4" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" RENAME COLUMN "companyIds" TO "companyId"`); + await queryRunner.query( + `CREATE TABLE "company_info" ("id" uuid NOT NULL, CONSTRAINT "PK_88c3e323679d0747ffbb83f3f78" PRIMARY KEY ("id"))`, + ); + await queryRunner.query(`ALTER TABLE "connection" ADD "companyId" uuid`); + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "companyId"`); + await queryRunner.query(`ALTER TABLE "user" ADD "companyId" uuid`); + await queryRunner.query( + `ALTER TABLE "user" ADD CONSTRAINT "FK_86586021a26d1180b0968f98502" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "connection" ADD CONSTRAINT "FK_3c56723750fad39864878239cf4" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_3c56723750fad39864878239cf4"`); - await queryRunner.query(`ALTER TABLE "user" DROP CONSTRAINT "FK_86586021a26d1180b0968f98502"`); - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "companyId"`); - await queryRunner.query(`ALTER TABLE "user" ADD "companyId" uuid array NOT NULL DEFAULT '{}'`); - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "companyId"`); - await queryRunner.query(`DROP TABLE "company_info"`); - await queryRunner.query(`ALTER TABLE "user" RENAME COLUMN "companyId" TO "companyIds"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_3c56723750fad39864878239cf4"`); + await queryRunner.query(`ALTER TABLE "user" DROP CONSTRAINT "FK_86586021a26d1180b0968f98502"`); + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "companyId"`); + await queryRunner.query(`ALTER TABLE "user" ADD "companyId" uuid array NOT NULL DEFAULT '{}'`); + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "companyId"`); + await queryRunner.query(`DROP TABLE "company_info"`); + await queryRunner.query(`ALTER TABLE "user" RENAME COLUMN "companyId" TO "companyIds"`); + } } diff --git a/backend/src/migrations/1695740265059-AddedRolePropertyForUserAddedInvitationEntity.ts b/backend/src/migrations/1695740265059-AddedRolePropertyForUserAddedInvitationEntity.ts index f1a078847..d1e3d2798 100644 --- a/backend/src/migrations/1695740265059-AddedRolePropertyForUserAddedInvitationEntity.ts +++ b/backend/src/migrations/1695740265059-AddedRolePropertyForUserAddedInvitationEntity.ts @@ -1,22 +1,25 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddedRolePropertyForUserAddedInvitationEntity1695740265059 implements MigrationInterface { - name = 'AddedRolePropertyForUserAddedInvitationEntity1695740265059' + name = 'AddedRolePropertyForUserAddedInvitationEntity1695740265059'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TYPE "public"."invitation_in_company_role_enum" AS ENUM('ADMIN', 'USER')`); - await queryRunner.query(`CREATE TABLE "invitation_in_company" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "verification_string" character varying, "groupId" character varying, "inviterId" character varying, "invitedUserEmail" character varying, "role" "public"."invitation_in_company_role_enum" NOT NULL DEFAULT 'USER', "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "companyId" uuid, CONSTRAINT "PK_b4dd40d00ac78218d9499f1bd7f" PRIMARY KEY ("id"))`); - await queryRunner.query(`CREATE TYPE "public"."user_role_enum" AS ENUM('ADMIN', 'USER')`); - await queryRunner.query(`ALTER TABLE "user" ADD "role" "public"."user_role_enum" NOT NULL DEFAULT 'USER'`); - await queryRunner.query(`ALTER TABLE "invitation_in_company" ADD CONSTRAINT "FK_1a871b48d2248201b961f3d111c" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "invitation_in_company" DROP CONSTRAINT "FK_1a871b48d2248201b961f3d111c"`); - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "role"`); - await queryRunner.query(`DROP TYPE "public"."user_role_enum"`); - await queryRunner.query(`DROP TABLE "invitation_in_company"`); - await queryRunner.query(`DROP TYPE "public"."invitation_in_company_role_enum"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TYPE "public"."invitation_in_company_role_enum" AS ENUM('ADMIN', 'USER')`); + await queryRunner.query( + `CREATE TABLE "invitation_in_company" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "verification_string" character varying, "groupId" character varying, "inviterId" character varying, "invitedUserEmail" character varying, "role" "public"."invitation_in_company_role_enum" NOT NULL DEFAULT 'USER', "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "companyId" uuid, CONSTRAINT "PK_b4dd40d00ac78218d9499f1bd7f" PRIMARY KEY ("id"))`, + ); + await queryRunner.query(`CREATE TYPE "public"."user_role_enum" AS ENUM('ADMIN', 'USER')`); + await queryRunner.query(`ALTER TABLE "user" ADD "role" "public"."user_role_enum" NOT NULL DEFAULT 'USER'`); + await queryRunner.query( + `ALTER TABLE "invitation_in_company" ADD CONSTRAINT "FK_1a871b48d2248201b961f3d111c" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "invitation_in_company" DROP CONSTRAINT "FK_1a871b48d2248201b961f3d111c"`); + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "role"`); + await queryRunner.query(`DROP TYPE "public"."user_role_enum"`); + await queryRunner.query(`DROP TABLE "invitation_in_company"`); + await queryRunner.query(`DROP TYPE "public"."invitation_in_company_role_enum"`); + } } diff --git a/backend/src/migrations/1700575487164-AddNameInCompanyInfoEntity.ts b/backend/src/migrations/1700575487164-AddNameInCompanyInfoEntity.ts index e40edb82c..0ac633810 100644 --- a/backend/src/migrations/1700575487164-AddNameInCompanyInfoEntity.ts +++ b/backend/src/migrations/1700575487164-AddNameInCompanyInfoEntity.ts @@ -1,17 +1,17 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddNameInCompanyInfoEntity1700575487164 implements MigrationInterface { - name = 'AddNameInCompanyInfoEntity1700575487164'; + name = 'AddNameInCompanyInfoEntity1700575487164'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "company_info" ADD "name" character varying(255)`); - await queryRunner.query( - `ALTER TABLE "company_info" ADD CONSTRAINT "UQ_a46f1a801acc21386a5fce0d420" UNIQUE ("name")`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "company_info" ADD "name" character varying(255)`); + await queryRunner.query( + `ALTER TABLE "company_info" ADD CONSTRAINT "UQ_a46f1a801acc21386a5fce0d420" UNIQUE ("name")`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "company_info" DROP CONSTRAINT "UQ_a46f1a801acc21386a5fce0d420"`); - await queryRunner.query(`ALTER TABLE "company_info" DROP COLUMN "name"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "company_info" DROP CONSTRAINT "UQ_a46f1a801acc21386a5fce0d420"`); + await queryRunner.query(`ALTER TABLE "company_info" DROP COLUMN "name"`); + } } diff --git a/backend/src/migrations/1701092024946-AddUserSessionSettings.ts b/backend/src/migrations/1701092024946-AddUserSessionSettings.ts index 591574740..aece22232 100644 --- a/backend/src/migrations/1701092024946-AddUserSessionSettings.ts +++ b/backend/src/migrations/1701092024946-AddUserSessionSettings.ts @@ -1,15 +1,15 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddUserSessionSettings1701092024946 implements MigrationInterface { - name = 'AddUserSessionSettings1701092024946'; + name = 'AddUserSessionSettings1701092024946'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TABLE "user_session_settings" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "userId" uuid NOT NULL, "userSettings" json, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "UQ_6cc8775feee5687ec999d8a1e5c" UNIQUE ("userId"), CONSTRAINT "PK_09fce02394b4e15e98cf84ba69c" PRIMARY KEY ("id"))`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "user_session_settings" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "userId" uuid NOT NULL, "userSettings" json, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), CONSTRAINT "UQ_6cc8775feee5687ec999d8a1e5c" UNIQUE ("userId"), CONSTRAINT "PK_09fce02394b4e15e98cf84ba69c" PRIMARY KEY ("id"))`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`DROP TABLE "user_session_settings"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`DROP TABLE "user_session_settings"`); + } } diff --git a/backend/src/migrations/1701250872329-AddTablesAuditInConnectionEntity.ts b/backend/src/migrations/1701250872329-AddTablesAuditInConnectionEntity.ts index bbf0bdb80..303f112be 100644 --- a/backend/src/migrations/1701250872329-AddTablesAuditInConnectionEntity.ts +++ b/backend/src/migrations/1701250872329-AddTablesAuditInConnectionEntity.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddTablesAuditInConnectionEntity1701250872329 implements MigrationInterface { - name = 'AddTablesAuditInConnectionEntity1701250872329'; + name = 'AddTablesAuditInConnectionEntity1701250872329'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" ADD "tables_audit" boolean NOT NULL DEFAULT true`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" ADD "tables_audit" boolean NOT NULL DEFAULT true`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "tables_audit"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "tables_audit"`); + } } diff --git a/backend/src/migrations/1701690979706-RemoveTableAuditPropertyFromConnectionEntity.ts b/backend/src/migrations/1701690979706-RemoveTableAuditPropertyFromConnectionEntity.ts index 4f1fab8b9..39663d4ab 100644 --- a/backend/src/migrations/1701690979706-RemoveTableAuditPropertyFromConnectionEntity.ts +++ b/backend/src/migrations/1701690979706-RemoveTableAuditPropertyFromConnectionEntity.ts @@ -1,14 +1,13 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class RemoveTableAuditPropertyFromConnectionEntity1701690979706 implements MigrationInterface { - name = 'RemoveTableAuditPropertyFromConnectionEntity1701690979706' + name = 'RemoveTableAuditPropertyFromConnectionEntity1701690979706'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "tables_audit"`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" ADD "tables_audit" boolean NOT NULL DEFAULT true`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "tables_audit"`); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" ADD "tables_audit" boolean NOT NULL DEFAULT true`); + } } diff --git a/backend/src/migrations/1701692512632-AddTablesAuditOptionInConnectionProperties.ts b/backend/src/migrations/1701692512632-AddTablesAuditOptionInConnectionProperties.ts index 0aa5bc7a2..51a95ed06 100644 --- a/backend/src/migrations/1701692512632-AddTablesAuditOptionInConnectionProperties.ts +++ b/backend/src/migrations/1701692512632-AddTablesAuditOptionInConnectionProperties.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddTablesAuditOptionInConnectionProperties1701692512632 implements MigrationInterface { - name = 'AddTablesAuditOptionInConnectionProperties1701692512632'; + name = 'AddTablesAuditOptionInConnectionProperties1701692512632'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "tables_audit" boolean NOT NULL DEFAULT true`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "tables_audit" boolean NOT NULL DEFAULT true`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "tables_audit"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "tables_audit"`); + } } diff --git a/backend/src/migrations/1702029067334-AddedExternalProviderRegistrationPropertyInUserEntity.ts b/backend/src/migrations/1702029067334-AddedExternalProviderRegistrationPropertyInUserEntity.ts index 038eea090..9e96dea94 100644 --- a/backend/src/migrations/1702029067334-AddedExternalProviderRegistrationPropertyInUserEntity.ts +++ b/backend/src/migrations/1702029067334-AddedExternalProviderRegistrationPropertyInUserEntity.ts @@ -1,19 +1,19 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddedExternalProviderRegistrationPropertyInUserEntity1702029067334 implements MigrationInterface { - name = 'AddedExternalProviderRegistrationPropertyInUserEntity1702029067334'; + name = 'AddedExternalProviderRegistrationPropertyInUserEntity1702029067334'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TYPE "public"."user_externalregistrationprovider_enum" AS ENUM('GOOGLE', 'GITHUB')`, - ); - await queryRunner.query( - `ALTER TABLE "user" ADD "externalRegistrationProvider" "public"."user_externalregistrationprovider_enum"`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TYPE "public"."user_externalregistrationprovider_enum" AS ENUM('GOOGLE', 'GITHUB')`, + ); + await queryRunner.query( + `ALTER TABLE "user" ADD "externalRegistrationProvider" "public"."user_externalregistrationprovider_enum"`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "externalRegistrationProvider"`); - await queryRunner.query(`DROP TYPE "public"."user_externalregistrationprovider_enum"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "externalRegistrationProvider"`); + await queryRunner.query(`DROP TYPE "public"."user_externalregistrationprovider_enum"`); + } } diff --git a/backend/src/migrations/1702644802462-AddCascadePropertyInUserEntityForCompanyInfo.ts b/backend/src/migrations/1702644802462-AddCascadePropertyInUserEntityForCompanyInfo.ts index 917b0e76c..ed11bd4fc 100644 --- a/backend/src/migrations/1702644802462-AddCascadePropertyInUserEntityForCompanyInfo.ts +++ b/backend/src/migrations/1702644802462-AddCascadePropertyInUserEntityForCompanyInfo.ts @@ -1,19 +1,19 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddCascadePropertyInUserEntityForCompanyInfo1702644802462 implements MigrationInterface { - name = 'AddCascadePropertyInUserEntityForCompanyInfo1702644802462'; + name = 'AddCascadePropertyInUserEntityForCompanyInfo1702644802462'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" DROP CONSTRAINT "FK_86586021a26d1180b0968f98502"`); - await queryRunner.query( - `ALTER TABLE "user" ADD CONSTRAINT "FK_86586021a26d1180b0968f98502" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE SET NULL ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" DROP CONSTRAINT "FK_86586021a26d1180b0968f98502"`); + await queryRunner.query( + `ALTER TABLE "user" ADD CONSTRAINT "FK_86586021a26d1180b0968f98502" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE SET NULL ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" DROP CONSTRAINT "FK_86586021a26d1180b0968f98502"`); - await queryRunner.query( - `ALTER TABLE "user" ADD CONSTRAINT "FK_86586021a26d1180b0968f98502" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" DROP CONSTRAINT "FK_86586021a26d1180b0968f98502"`); + await queryRunner.query( + `ALTER TABLE "user" ADD CONSTRAINT "FK_86586021a26d1180b0968f98502" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + } } diff --git a/backend/src/migrations/1704385127896-AddedCascadeOptionForAuthorInConnectionEntity.ts b/backend/src/migrations/1704385127896-AddedCascadeOptionForAuthorInConnectionEntity.ts index f4ac8ce31..7be6c7a2a 100644 --- a/backend/src/migrations/1704385127896-AddedCascadeOptionForAuthorInConnectionEntity.ts +++ b/backend/src/migrations/1704385127896-AddedCascadeOptionForAuthorInConnectionEntity.ts @@ -1,19 +1,19 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddedCascadeOptionForAuthorInConnectionEntity1704385127896 implements MigrationInterface { - name = 'AddedCascadeOptionForAuthorInConnectionEntity1704385127896'; + name = 'AddedCascadeOptionForAuthorInConnectionEntity1704385127896'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); - await queryRunner.query( - `ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); + await queryRunner.query( + `ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE SET NULL ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); - await queryRunner.query( - `ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "FK_e70264c101ff77ebe3380e64c67"`); + await queryRunner.query( + `ALTER TABLE "connection" ADD CONSTRAINT "FK_e70264c101ff77ebe3380e64c67" FOREIGN KEY ("authorId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } } diff --git a/backend/src/migrations/1704572940909-AddNullableTrueForAuthorIdInConnectionEntity.ts b/backend/src/migrations/1704572940909-AddNullableTrueForAuthorIdInConnectionEntity.ts index 6dd69c6c1..d4399d157 100644 --- a/backend/src/migrations/1704572940909-AddNullableTrueForAuthorIdInConnectionEntity.ts +++ b/backend/src/migrations/1704572940909-AddNullableTrueForAuthorIdInConnectionEntity.ts @@ -1,11 +1,11 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddNullableTrueForAuthorIdInConnectionEntity1704572940909 implements MigrationInterface { - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "authorId" DROP NOT NULL`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "authorId" DROP NOT NULL`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "authorId" SET NOT NULL`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "authorId" SET NOT NULL`); + } } diff --git a/backend/src/migrations/1704808026942-RemovedStripeIdFromUserEntity.ts b/backend/src/migrations/1704808026942-RemovedStripeIdFromUserEntity.ts index f8f71c9df..7cb889160 100644 --- a/backend/src/migrations/1704808026942-RemovedStripeIdFromUserEntity.ts +++ b/backend/src/migrations/1704808026942-RemovedStripeIdFromUserEntity.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class RemovedStripeIdFromUserEntity1704808026942 implements MigrationInterface { - name = 'RemovedStripeIdFromUserEntity1704808026942'; + name = 'RemovedStripeIdFromUserEntity1704808026942'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "stripeId"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "stripeId"`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" ADD "stripeId" character varying`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" ADD "stripeId" character varying`); + } } diff --git a/backend/src/migrations/1705927093291-ChangeCronJobsEntity.ts b/backend/src/migrations/1705927093291-ChangeCronJobsEntity.ts index dc794728a..a060d2be2 100644 --- a/backend/src/migrations/1705927093291-ChangeCronJobsEntity.ts +++ b/backend/src/migrations/1705927093291-ChangeCronJobsEntity.ts @@ -1,25 +1,25 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class ChangeCronJobsEntity1705927093291 implements MigrationInterface { - name = 'ChangeCronJobsEntity1705927093291'; + name = 'ChangeCronJobsEntity1705927093291'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "job_list" DROP CONSTRAINT "PK_d14e7f19b86450b1cafc689ca41"`); - await queryRunner.query(`ALTER TABLE "job_list" DROP COLUMN "job_key"`); - await queryRunner.query(`ALTER TABLE "job_list" ADD "id" integer NOT NULL`); - await queryRunner.query( - `ALTER TABLE "job_list" ADD CONSTRAINT "PK_5ce383619e96dd36760166222f4" PRIMARY KEY ("id")`, - ); - await queryRunner.query(`ALTER TABLE "job_list" ADD "createdAt" TIMESTAMP NOT NULL DEFAULT now()`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "job_list" DROP CONSTRAINT "PK_d14e7f19b86450b1cafc689ca41"`); + await queryRunner.query(`ALTER TABLE "job_list" DROP COLUMN "job_key"`); + await queryRunner.query(`ALTER TABLE "job_list" ADD "id" integer NOT NULL`); + await queryRunner.query( + `ALTER TABLE "job_list" ADD CONSTRAINT "PK_5ce383619e96dd36760166222f4" PRIMARY KEY ("id")`, + ); + await queryRunner.query(`ALTER TABLE "job_list" ADD "createdAt" TIMESTAMP NOT NULL DEFAULT now()`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "job_list" DROP COLUMN "createdAt"`); - await queryRunner.query(`ALTER TABLE "job_list" DROP CONSTRAINT "PK_5ce383619e96dd36760166222f4"`); - await queryRunner.query(`ALTER TABLE "job_list" DROP COLUMN "id"`); - await queryRunner.query(`ALTER TABLE "job_list" ADD "job_key" character varying(100) NOT NULL`); - await queryRunner.query( - `ALTER TABLE "job_list" ADD CONSTRAINT "PK_d14e7f19b86450b1cafc689ca41" PRIMARY KEY ("job_key")`, - ); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "job_list" DROP COLUMN "createdAt"`); + await queryRunner.query(`ALTER TABLE "job_list" DROP CONSTRAINT "PK_5ce383619e96dd36760166222f4"`); + await queryRunner.query(`ALTER TABLE "job_list" DROP COLUMN "id"`); + await queryRunner.query(`ALTER TABLE "job_list" ADD "job_key" character varying(100) NOT NULL`); + await queryRunner.query( + `ALTER TABLE "job_list" ADD CONSTRAINT "PK_d14e7f19b86450b1cafc689ca41" PRIMARY KEY ("job_key")`, + ); + } } diff --git a/backend/src/migrations/1708952120950-Add2faPropertyInConnectionInfo.ts b/backend/src/migrations/1708952120950-Add2faPropertyInConnectionInfo.ts index 5ce7e045b..f9896c360 100644 --- a/backend/src/migrations/1708952120950-Add2faPropertyInConnectionInfo.ts +++ b/backend/src/migrations/1708952120950-Add2faPropertyInConnectionInfo.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class Add2faPropertyInConnectionInfo1708952120950 implements MigrationInterface { - name = 'Add2faPropertyInConnectionInfo1708952120950'; + name = 'Add2faPropertyInConnectionInfo1708952120950'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "company_info" ADD "is2faEnabled" boolean NOT NULL DEFAULT false`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "company_info" ADD "is2faEnabled" boolean NOT NULL DEFAULT false`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "company_info" DROP COLUMN "is2faEnabled"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "company_info" DROP COLUMN "is2faEnabled"`); + } } diff --git a/backend/src/migrations/1710413135309-AddSuspendedPropertyToUserEntity.ts b/backend/src/migrations/1710413135309-AddSuspendedPropertyToUserEntity.ts index 5f3869f9f..244308a24 100644 --- a/backend/src/migrations/1710413135309-AddSuspendedPropertyToUserEntity.ts +++ b/backend/src/migrations/1710413135309-AddSuspendedPropertyToUserEntity.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddSuspendedPropertyToUserEntity1710413135309 implements MigrationInterface { - name = 'AddSuspendedPropertyToUserEntity1710413135309'; + name = 'AddSuspendedPropertyToUserEntity1710413135309'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" ADD "suspended" boolean NOT NULL DEFAULT false`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" ADD "suspended" boolean NOT NULL DEFAULT false`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "suspended"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "suspended"`); + } } diff --git a/backend/src/migrations/1713430478571-CompanyNameNonUnique.ts b/backend/src/migrations/1713430478571-CompanyNameNonUnique.ts index 2aafe96e4..811f8e45c 100644 --- a/backend/src/migrations/1713430478571-CompanyNameNonUnique.ts +++ b/backend/src/migrations/1713430478571-CompanyNameNonUnique.ts @@ -1,15 +1,15 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class CompanyNameNonUnique1713430478571 implements MigrationInterface { - name = 'CompanyNameNonUnique1713430478571'; + name = 'CompanyNameNonUnique1713430478571'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "company_info" DROP CONSTRAINT "UQ_a46f1a801acc21386a5fce0d420"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "company_info" DROP CONSTRAINT "UQ_a46f1a801acc21386a5fce0d420"`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `ALTER TABLE "company_info" ADD CONSTRAINT "UQ_a46f1a801acc21386a5fce0d420" UNIQUE ("name")`, - ); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "company_info" ADD CONSTRAINT "UQ_a46f1a801acc21386a5fce0d420" UNIQUE ("name")`, + ); + } } diff --git a/backend/src/migrations/1715176561446-AddAuthSourcePropertyInConnectionEntity.ts b/backend/src/migrations/1715176561446-AddAuthSourcePropertyInConnectionEntity.ts index c89c9a48f..ef38f1ff9 100644 --- a/backend/src/migrations/1715176561446-AddAuthSourcePropertyInConnectionEntity.ts +++ b/backend/src/migrations/1715176561446-AddAuthSourcePropertyInConnectionEntity.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddAuthSourcePropertyInConnectionEntity1715176561446 implements MigrationInterface { - name = 'AddAuthSourcePropertyInConnectionEntity1715176561446'; + name = 'AddAuthSourcePropertyInConnectionEntity1715176561446'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" ADD "authSource" character varying`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" ADD "authSource" character varying`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "authSource"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "authSource"`); + } } diff --git a/backend/src/migrations/1717155859650-AddTableTriggersEntity.ts b/backend/src/migrations/1717155859650-AddTableTriggersEntity.ts index 30702fe66..dafb85a4b 100644 --- a/backend/src/migrations/1717155859650-AddTableTriggersEntity.ts +++ b/backend/src/migrations/1717155859650-AddTableTriggersEntity.ts @@ -1,39 +1,39 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddTableTriggersEntity1717155859650 implements MigrationInterface { - name = 'AddTableTriggersEntity1717155859650'; + name = 'AddTableTriggersEntity1717155859650'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TYPE "public"."table_triggers_trigger_events_enum" AS ENUM('ADD_ROW', 'UPDATE_ROW', 'DELETE_ROW')`, - ); - await queryRunner.query( - `CREATE TABLE "table_triggers" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "table_name" character varying, "created_at" TIMESTAMP, "trigger_events" "public"."table_triggers_trigger_events_enum" array NOT NULL DEFAULT '{ADD_ROW}', "connectionId" uuid, CONSTRAINT "PK_e5b00855e953fa2066943ac41b4" PRIMARY KEY ("id"))`, - ); - await queryRunner.query( - `CREATE TABLE "triggers_actions" ("table_triggers" uuid NOT NULL, "table_actions" uuid NOT NULL, CONSTRAINT "PK_d5a10491002c0bfd3b3331e6d44" PRIMARY KEY ("table_triggers", "table_actions"))`, - ); - await queryRunner.query(`CREATE INDEX "IDX_333cff6a1e46fd3bb2764133de" ON "triggers_actions" ("table_triggers") `); - await queryRunner.query(`CREATE INDEX "IDX_71e326e6659fa8c2b724e720c8" ON "triggers_actions" ("table_actions") `); - await queryRunner.query( - `ALTER TABLE "table_triggers" ADD CONSTRAINT "FK_937487c7a49aefc776beb196f42" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "triggers_actions" ADD CONSTRAINT "FK_333cff6a1e46fd3bb2764133de7" FOREIGN KEY ("table_triggers") REFERENCES "table_triggers"("id") ON DELETE CASCADE ON UPDATE CASCADE`, - ); - await queryRunner.query( - `ALTER TABLE "triggers_actions" ADD CONSTRAINT "FK_71e326e6659fa8c2b724e720c85" FOREIGN KEY ("table_actions") REFERENCES "table_actions"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TYPE "public"."table_triggers_trigger_events_enum" AS ENUM('ADD_ROW', 'UPDATE_ROW', 'DELETE_ROW')`, + ); + await queryRunner.query( + `CREATE TABLE "table_triggers" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "table_name" character varying, "created_at" TIMESTAMP, "trigger_events" "public"."table_triggers_trigger_events_enum" array NOT NULL DEFAULT '{ADD_ROW}', "connectionId" uuid, CONSTRAINT "PK_e5b00855e953fa2066943ac41b4" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "triggers_actions" ("table_triggers" uuid NOT NULL, "table_actions" uuid NOT NULL, CONSTRAINT "PK_d5a10491002c0bfd3b3331e6d44" PRIMARY KEY ("table_triggers", "table_actions"))`, + ); + await queryRunner.query(`CREATE INDEX "IDX_333cff6a1e46fd3bb2764133de" ON "triggers_actions" ("table_triggers") `); + await queryRunner.query(`CREATE INDEX "IDX_71e326e6659fa8c2b724e720c8" ON "triggers_actions" ("table_actions") `); + await queryRunner.query( + `ALTER TABLE "table_triggers" ADD CONSTRAINT "FK_937487c7a49aefc776beb196f42" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "triggers_actions" ADD CONSTRAINT "FK_333cff6a1e46fd3bb2764133de7" FOREIGN KEY ("table_triggers") REFERENCES "table_triggers"("id") ON DELETE CASCADE ON UPDATE CASCADE`, + ); + await queryRunner.query( + `ALTER TABLE "triggers_actions" ADD CONSTRAINT "FK_71e326e6659fa8c2b724e720c85" FOREIGN KEY ("table_actions") REFERENCES "table_actions"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "triggers_actions" DROP CONSTRAINT "FK_71e326e6659fa8c2b724e720c85"`); - await queryRunner.query(`ALTER TABLE "triggers_actions" DROP CONSTRAINT "FK_333cff6a1e46fd3bb2764133de7"`); - await queryRunner.query(`ALTER TABLE "table_triggers" DROP CONSTRAINT "FK_937487c7a49aefc776beb196f42"`); - await queryRunner.query(`DROP INDEX "public"."IDX_71e326e6659fa8c2b724e720c8"`); - await queryRunner.query(`DROP INDEX "public"."IDX_333cff6a1e46fd3bb2764133de"`); - await queryRunner.query(`DROP TABLE "triggers_actions"`); - await queryRunner.query(`DROP TABLE "table_triggers"`); - await queryRunner.query(`DROP TYPE "public"."table_triggers_trigger_events_enum"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "triggers_actions" DROP CONSTRAINT "FK_71e326e6659fa8c2b724e720c85"`); + await queryRunner.query(`ALTER TABLE "triggers_actions" DROP CONSTRAINT "FK_333cff6a1e46fd3bb2764133de7"`); + await queryRunner.query(`ALTER TABLE "table_triggers" DROP CONSTRAINT "FK_937487c7a49aefc776beb196f42"`); + await queryRunner.query(`DROP INDEX "public"."IDX_71e326e6659fa8c2b724e720c8"`); + await queryRunner.query(`DROP INDEX "public"."IDX_333cff6a1e46fd3bb2764133de"`); + await queryRunner.query(`DROP TABLE "triggers_actions"`); + await queryRunner.query(`DROP TABLE "table_triggers"`); + await queryRunner.query(`DROP TYPE "public"."table_triggers_trigger_events_enum"`); + } } diff --git a/backend/src/migrations/1717677116163-AddSlackAndEmailPropertiesInTableActionEntity.ts b/backend/src/migrations/1717677116163-AddSlackAndEmailPropertiesInTableActionEntity.ts index 369ed9a8e..e8dfacbcb 100644 --- a/backend/src/migrations/1717677116163-AddSlackAndEmailPropertiesInTableActionEntity.ts +++ b/backend/src/migrations/1717677116163-AddSlackAndEmailPropertiesInTableActionEntity.ts @@ -1,25 +1,25 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddSlackAndEmailPropertiesInTableActionEntity1717677116163 implements MigrationInterface { - name = 'AddSlackAndEmailPropertiesInTableActionEntity1717677116163'; + name = 'AddSlackAndEmailPropertiesInTableActionEntity1717677116163'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TYPE "public"."table_actions_method_enum" AS ENUM('HTTP', 'ZAPIER', 'WEBHOOK', 'EMAIL', 'SLACK')`, - ); - await queryRunner.query( - `ALTER TABLE "table_actions" ADD "method" "public"."table_actions_method_enum" NOT NULL DEFAULT 'HTTP'`, - ); - await queryRunner.query(`ALTER TABLE "table_actions" ADD "slack_channel" character varying`); - await queryRunner.query(`ALTER TABLE "table_actions" ADD "slack_bot_token" character varying`); - await queryRunner.query(`ALTER TABLE "table_actions" ADD "emails" character varying array NOT NULL DEFAULT '{}'`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TYPE "public"."table_actions_method_enum" AS ENUM('HTTP', 'ZAPIER', 'WEBHOOK', 'EMAIL', 'SLACK')`, + ); + await queryRunner.query( + `ALTER TABLE "table_actions" ADD "method" "public"."table_actions_method_enum" NOT NULL DEFAULT 'HTTP'`, + ); + await queryRunner.query(`ALTER TABLE "table_actions" ADD "slack_channel" character varying`); + await queryRunner.query(`ALTER TABLE "table_actions" ADD "slack_bot_token" character varying`); + await queryRunner.query(`ALTER TABLE "table_actions" ADD "emails" character varying array NOT NULL DEFAULT '{}'`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "emails"`); - await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "slack_bot_token"`); - await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "slack_channel"`); - await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "method"`); - await queryRunner.query(`DROP TYPE "public"."table_actions_method_enum"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "emails"`); + await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "slack_bot_token"`); + await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "slack_channel"`); + await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "method"`); + await queryRunner.query(`DROP TYPE "public"."table_actions_method_enum"`); + } } diff --git a/backend/src/migrations/1718277289830-AddCSVPropertiesInTableSettingsEntity.ts b/backend/src/migrations/1718277289830-AddCSVPropertiesInTableSettingsEntity.ts index aa8efb4c3..713ea3945 100644 --- a/backend/src/migrations/1718277289830-AddCSVPropertiesInTableSettingsEntity.ts +++ b/backend/src/migrations/1718277289830-AddCSVPropertiesInTableSettingsEntity.ts @@ -1,15 +1,15 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddCSVPropertiesInTableSettingsEntity1718277289830 implements MigrationInterface { - name = 'AddCSVPropertiesInTableSettingsEntity1718277289830'; + name = 'AddCSVPropertiesInTableSettingsEntity1718277289830'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableSettings" ADD "allow_csv_export" boolean NOT NULL DEFAULT true`); - await queryRunner.query(`ALTER TABLE "tableSettings" ADD "allow_csv_import" boolean NOT NULL DEFAULT true`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableSettings" ADD "allow_csv_export" boolean NOT NULL DEFAULT true`); + await queryRunner.query(`ALTER TABLE "tableSettings" ADD "allow_csv_import" boolean NOT NULL DEFAULT true`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "allow_csv_import"`); - await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "allow_csv_export"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "allow_csv_import"`); + await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "allow_csv_export"`); + } } diff --git a/backend/src/migrations/1718701843492-ReworkTableActionEntityAddedSlackUrl.ts b/backend/src/migrations/1718701843492-ReworkTableActionEntityAddedSlackUrl.ts index 72597efb0..bb7c1539d 100644 --- a/backend/src/migrations/1718701843492-ReworkTableActionEntityAddedSlackUrl.ts +++ b/backend/src/migrations/1718701843492-ReworkTableActionEntityAddedSlackUrl.ts @@ -1,17 +1,17 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class ReworkTableActionEntityAddedSlackUrl1718701843492 implements MigrationInterface { - name = 'ReworkTableActionEntityAddedSlackUrl1718701843492'; + name = 'ReworkTableActionEntityAddedSlackUrl1718701843492'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "slack_channel"`); - await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "slack_bot_token"`); - await queryRunner.query(`ALTER TABLE "table_actions" ADD "slack_url" character varying`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "slack_channel"`); + await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "slack_bot_token"`); + await queryRunner.query(`ALTER TABLE "table_actions" ADD "slack_url" character varying`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "slack_url"`); - await queryRunner.query(`ALTER TABLE "table_actions" ADD "slack_bot_token" character varying`); - await queryRunner.query(`ALTER TABLE "table_actions" ADD "slack_channel" character varying`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "slack_url"`); + await queryRunner.query(`ALTER TABLE "table_actions" ADD "slack_bot_token" character varying`); + await queryRunner.query(`ALTER TABLE "table_actions" ADD "slack_channel" character varying`); + } } diff --git a/backend/src/migrations/1718789616020-RemoveIconTitlePropertyFromTableAction.ts b/backend/src/migrations/1718789616020-RemoveIconTitlePropertyFromTableAction.ts index 899ef1550..57a160eee 100644 --- a/backend/src/migrations/1718789616020-RemoveIconTitlePropertyFromTableAction.ts +++ b/backend/src/migrations/1718789616020-RemoveIconTitlePropertyFromTableAction.ts @@ -1,15 +1,15 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class RemoveIconTitlePropertyFromTableAction1718789616020 implements MigrationInterface { - name = 'RemoveIconTitlePropertyFromTableAction1718789616020'; + name = 'RemoveIconTitlePropertyFromTableAction1718789616020'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "title"`); - await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "icon"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "title"`); + await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "icon"`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_actions" ADD "icon" character varying`); - await queryRunner.query(`ALTER TABLE "table_actions" ADD "title" character varying`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_actions" ADD "icon" character varying`); + await queryRunner.query(`ALTER TABLE "table_actions" ADD "title" character varying`); + } } diff --git a/backend/src/migrations/1718799894813-ReworkTableTriggersIntoActionRules.ts b/backend/src/migrations/1718799894813-ReworkTableTriggersIntoActionRules.ts index a562fbde3..f29bb00dc 100644 --- a/backend/src/migrations/1718799894813-ReworkTableTriggersIntoActionRules.ts +++ b/backend/src/migrations/1718799894813-ReworkTableTriggersIntoActionRules.ts @@ -1,39 +1,39 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class ReworkTableTriggersIntoActionRules1718799894813 implements MigrationInterface { - name = 'ReworkTableTriggersIntoActionRules1718799894813'; + name = 'ReworkTableTriggersIntoActionRules1718799894813'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TYPE "public"."action_rules_trigger_events_enum" AS ENUM('ADD_ROW', 'UPDATE_ROW', 'DELETE_ROW')`, - ); - await queryRunner.query( - `CREATE TABLE "action_rules" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "table_name" character varying, "icon" character varying, "title" character varying, "created_at" TIMESTAMP, "trigger_events" "public"."action_rules_trigger_events_enum" array NOT NULL DEFAULT '{ADD_ROW}', "connectionId" uuid, CONSTRAINT "PK_01068b2203d4b60abd2d28d0538" PRIMARY KEY ("id"))`, - ); - await queryRunner.query( - `CREATE TABLE "rules_actions" ("action_rules" uuid NOT NULL, "table_actions" uuid NOT NULL, CONSTRAINT "PK_94e0a9f0ffebdd54de2802bda9c" PRIMARY KEY ("action_rules", "table_actions"))`, - ); - await queryRunner.query(`CREATE INDEX "IDX_2c65741fa2bec6a9d82f3f985b" ON "rules_actions" ("action_rules") `); - await queryRunner.query(`CREATE INDEX "IDX_da79a3ea2105544892c25c5fed" ON "rules_actions" ("table_actions") `); - await queryRunner.query( - `ALTER TABLE "action_rules" ADD CONSTRAINT "FK_754352f9577b1b87a4593eb6f4c" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "rules_actions" ADD CONSTRAINT "FK_2c65741fa2bec6a9d82f3f985be" FOREIGN KEY ("action_rules") REFERENCES "action_rules"("id") ON DELETE CASCADE ON UPDATE CASCADE`, - ); - await queryRunner.query( - `ALTER TABLE "rules_actions" ADD CONSTRAINT "FK_da79a3ea2105544892c25c5fed7" FOREIGN KEY ("table_actions") REFERENCES "table_actions"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TYPE "public"."action_rules_trigger_events_enum" AS ENUM('ADD_ROW', 'UPDATE_ROW', 'DELETE_ROW')`, + ); + await queryRunner.query( + `CREATE TABLE "action_rules" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "table_name" character varying, "icon" character varying, "title" character varying, "created_at" TIMESTAMP, "trigger_events" "public"."action_rules_trigger_events_enum" array NOT NULL DEFAULT '{ADD_ROW}', "connectionId" uuid, CONSTRAINT "PK_01068b2203d4b60abd2d28d0538" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "rules_actions" ("action_rules" uuid NOT NULL, "table_actions" uuid NOT NULL, CONSTRAINT "PK_94e0a9f0ffebdd54de2802bda9c" PRIMARY KEY ("action_rules", "table_actions"))`, + ); + await queryRunner.query(`CREATE INDEX "IDX_2c65741fa2bec6a9d82f3f985b" ON "rules_actions" ("action_rules") `); + await queryRunner.query(`CREATE INDEX "IDX_da79a3ea2105544892c25c5fed" ON "rules_actions" ("table_actions") `); + await queryRunner.query( + `ALTER TABLE "action_rules" ADD CONSTRAINT "FK_754352f9577b1b87a4593eb6f4c" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "rules_actions" ADD CONSTRAINT "FK_2c65741fa2bec6a9d82f3f985be" FOREIGN KEY ("action_rules") REFERENCES "action_rules"("id") ON DELETE CASCADE ON UPDATE CASCADE`, + ); + await queryRunner.query( + `ALTER TABLE "rules_actions" ADD CONSTRAINT "FK_da79a3ea2105544892c25c5fed7" FOREIGN KEY ("table_actions") REFERENCES "table_actions"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "rules_actions" DROP CONSTRAINT "FK_da79a3ea2105544892c25c5fed7"`); - await queryRunner.query(`ALTER TABLE "rules_actions" DROP CONSTRAINT "FK_2c65741fa2bec6a9d82f3f985be"`); - await queryRunner.query(`ALTER TABLE "action_rules" DROP CONSTRAINT "FK_754352f9577b1b87a4593eb6f4c"`); - await queryRunner.query(`DROP INDEX "public"."IDX_da79a3ea2105544892c25c5fed"`); - await queryRunner.query(`DROP INDEX "public"."IDX_2c65741fa2bec6a9d82f3f985b"`); - await queryRunner.query(`DROP TABLE "rules_actions"`); - await queryRunner.query(`DROP TABLE "action_rules"`); - await queryRunner.query(`DROP TYPE "public"."action_rules_trigger_events_enum"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "rules_actions" DROP CONSTRAINT "FK_da79a3ea2105544892c25c5fed7"`); + await queryRunner.query(`ALTER TABLE "rules_actions" DROP CONSTRAINT "FK_2c65741fa2bec6a9d82f3f985be"`); + await queryRunner.query(`ALTER TABLE "action_rules" DROP CONSTRAINT "FK_754352f9577b1b87a4593eb6f4c"`); + await queryRunner.query(`DROP INDEX "public"."IDX_da79a3ea2105544892c25c5fed"`); + await queryRunner.query(`DROP INDEX "public"."IDX_2c65741fa2bec6a9d82f3f985b"`); + await queryRunner.query(`DROP TABLE "rules_actions"`); + await queryRunner.query(`DROP TABLE "action_rules"`); + await queryRunner.query(`DROP TYPE "public"."action_rules_trigger_events_enum"`); + } } diff --git a/backend/src/migrations/1718801355447-RemoveIconAndTriggerEventsFromActionRules.ts b/backend/src/migrations/1718801355447-RemoveIconAndTriggerEventsFromActionRules.ts index 023e142cc..eab09ca24 100644 --- a/backend/src/migrations/1718801355447-RemoveIconAndTriggerEventsFromActionRules.ts +++ b/backend/src/migrations/1718801355447-RemoveIconAndTriggerEventsFromActionRules.ts @@ -1,21 +1,21 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class RemoveIconAndTriggerEventsFromActionRules1718801355447 implements MigrationInterface { - name = 'RemoveIconAndTriggerEventsFromActionRules1718801355447'; + name = 'RemoveIconAndTriggerEventsFromActionRules1718801355447'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "action_rules" DROP COLUMN "trigger_events"`); - await queryRunner.query(`DROP TYPE "public"."action_rules_trigger_events_enum"`); - await queryRunner.query(`ALTER TABLE "action_rules" DROP COLUMN "icon"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "action_rules" DROP COLUMN "trigger_events"`); + await queryRunner.query(`DROP TYPE "public"."action_rules_trigger_events_enum"`); + await queryRunner.query(`ALTER TABLE "action_rules" DROP COLUMN "icon"`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "action_rules" ADD "icon" character varying`); - await queryRunner.query( - `CREATE TYPE "public"."action_rules_trigger_events_enum" AS ENUM('ADD_ROW', 'UPDATE_ROW', 'DELETE_ROW')`, - ); - await queryRunner.query( - `ALTER TABLE "action_rules" ADD "trigger_events" "public"."action_rules_trigger_events_enum" array NOT NULL DEFAULT '{ADD_ROW}'`, - ); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "action_rules" ADD "icon" character varying`); + await queryRunner.query( + `CREATE TYPE "public"."action_rules_trigger_events_enum" AS ENUM('ADD_ROW', 'UPDATE_ROW', 'DELETE_ROW')`, + ); + await queryRunner.query( + `ALTER TABLE "action_rules" ADD "trigger_events" "public"."action_rules_trigger_events_enum" array NOT NULL DEFAULT '{ADD_ROW}'`, + ); + } } diff --git a/backend/src/migrations/1718874144113-RemoveRequireConfirmationReworkMethodEnumInTableAction.ts b/backend/src/migrations/1718874144113-RemoveRequireConfirmationReworkMethodEnumInTableAction.ts index 5bf74a6c7..422f9fa7b 100644 --- a/backend/src/migrations/1718874144113-RemoveRequireConfirmationReworkMethodEnumInTableAction.ts +++ b/backend/src/migrations/1718874144113-RemoveRequireConfirmationReworkMethodEnumInTableAction.ts @@ -1,37 +1,37 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class RemoveRequireConfirmationReworkMethodEnumInTableAction1718874144113 implements MigrationInterface { - name = 'RemoveRequireConfirmationReworkMethodEnumInTableAction1718874144113'; + name = 'RemoveRequireConfirmationReworkMethodEnumInTableAction1718874144113'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "require_confirmation"`); - await queryRunner.query( - `ALTER TYPE "public"."table_actions_method_enum" RENAME TO "table_actions_method_enum_old"`, - ); - await queryRunner.query( - `CREATE TYPE "public"."table_actions_method_enum" AS ENUM('ZAPIER', 'EMAIL', 'SLACK', 'URL')`, - ); - await queryRunner.query(`ALTER TABLE "table_actions" ALTER COLUMN "method" DROP DEFAULT`); - await queryRunner.query( - `ALTER TABLE "table_actions" ALTER COLUMN "method" TYPE "public"."table_actions_method_enum" USING replace("method"::"text", 'HTTP', 'URL')::"public"."table_actions_method_enum"`, - ); - await queryRunner.query(`ALTER TABLE "table_actions" ALTER COLUMN "method" SET DEFAULT 'URL'`); - await queryRunner.query(`DROP TYPE "public"."table_actions_method_enum_old"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "require_confirmation"`); + await queryRunner.query( + `ALTER TYPE "public"."table_actions_method_enum" RENAME TO "table_actions_method_enum_old"`, + ); + await queryRunner.query( + `CREATE TYPE "public"."table_actions_method_enum" AS ENUM('ZAPIER', 'EMAIL', 'SLACK', 'URL')`, + ); + await queryRunner.query(`ALTER TABLE "table_actions" ALTER COLUMN "method" DROP DEFAULT`); + await queryRunner.query( + `ALTER TABLE "table_actions" ALTER COLUMN "method" TYPE "public"."table_actions_method_enum" USING replace("method"::"text", 'HTTP', 'URL')::"public"."table_actions_method_enum"`, + ); + await queryRunner.query(`ALTER TABLE "table_actions" ALTER COLUMN "method" SET DEFAULT 'URL'`); + await queryRunner.query(`DROP TYPE "public"."table_actions_method_enum_old"`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TYPE "public"."table_actions_method_enum_old" AS ENUM('HTTP', 'ZAPIER', 'WEBHOOK', 'EMAIL', 'SLACK')`, - ); - await queryRunner.query(`ALTER TABLE "table_actions" ALTER COLUMN "method" DROP DEFAULT`); - await queryRunner.query( - `ALTER TABLE "table_actions" ALTER COLUMN "method" TYPE "public"."table_actions_method_enum_old" USING "method"::"text"::"public"."table_actions_method_enum_old"`, - ); - await queryRunner.query(`ALTER TABLE "table_actions" ALTER COLUMN "method" SET DEFAULT 'HTTP'`); - await queryRunner.query(`DROP TYPE "public"."table_actions_method_enum"`); - await queryRunner.query( - `ALTER TYPE "public"."table_actions_method_enum_old" RENAME TO "table_actions_method_enum"`, - ); - await queryRunner.query(`ALTER TABLE "table_actions" ADD "require_confirmation" boolean NOT NULL DEFAULT false`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TYPE "public"."table_actions_method_enum_old" AS ENUM('HTTP', 'ZAPIER', 'WEBHOOK', 'EMAIL', 'SLACK')`, + ); + await queryRunner.query(`ALTER TABLE "table_actions" ALTER COLUMN "method" DROP DEFAULT`); + await queryRunner.query( + `ALTER TABLE "table_actions" ALTER COLUMN "method" TYPE "public"."table_actions_method_enum_old" USING "method"::"text"::"public"."table_actions_method_enum_old"`, + ); + await queryRunner.query(`ALTER TABLE "table_actions" ALTER COLUMN "method" SET DEFAULT 'HTTP'`); + await queryRunner.query(`DROP TYPE "public"."table_actions_method_enum"`); + await queryRunner.query( + `ALTER TYPE "public"."table_actions_method_enum_old" RENAME TO "table_actions_method_enum"`, + ); + await queryRunner.query(`ALTER TABLE "table_actions" ADD "require_confirmation" boolean NOT NULL DEFAULT false`); + } } diff --git a/backend/src/migrations/1718965562799-AddActionEventEntityAndRelations.ts b/backend/src/migrations/1718965562799-AddActionEventEntityAndRelations.ts index 15bc3da32..9fda8c226 100644 --- a/backend/src/migrations/1718965562799-AddActionEventEntityAndRelations.ts +++ b/backend/src/migrations/1718965562799-AddActionEventEntityAndRelations.ts @@ -1,37 +1,37 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddActionEventEntityAndRelations1718965562799 implements MigrationInterface { - name = 'AddActionEventEntityAndRelations1718965562799'; + name = 'AddActionEventEntityAndRelations1718965562799'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TYPE "public"."action_events_event_enum" AS ENUM('ADD_ROW', 'UPDATE_ROW', 'DELETE_ROW', 'CUSTOM')`, - ); - await queryRunner.query( - `CREATE TABLE "action_events" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "event" "public"."action_events_event_enum" NOT NULL DEFAULT 'CUSTOM', "title" character varying, "icon" character varying, "table_name" character varying, "created_at" TIMESTAMP, "require_confirmation" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_38b3cd177b610ee89f23bec7ea8" PRIMARY KEY ("id"))`, - ); - await queryRunner.query( - `CREATE TABLE "rules_events" ("action_rules" uuid NOT NULL, "action_events" uuid NOT NULL, CONSTRAINT "PK_3a51ebca253c2305650ab97a699" PRIMARY KEY ("action_rules", "action_events"))`, - ); - await queryRunner.query(`CREATE INDEX "IDX_5219b43c93dfa03f98eec58e98" ON "rules_events" ("action_rules") `); - await queryRunner.query(`CREATE INDEX "IDX_3f0cd18797ae23deb078612b6d" ON "rules_events" ("action_events") `); - await queryRunner.query(`ALTER TABLE "table_actions" ADD "created_at" TIMESTAMP`); - await queryRunner.query( - `ALTER TABLE "rules_events" ADD CONSTRAINT "FK_5219b43c93dfa03f98eec58e98f" FOREIGN KEY ("action_rules") REFERENCES "action_rules"("id") ON DELETE CASCADE ON UPDATE CASCADE`, - ); - await queryRunner.query( - `ALTER TABLE "rules_events" ADD CONSTRAINT "FK_3f0cd18797ae23deb078612b6dd" FOREIGN KEY ("action_events") REFERENCES "action_events"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TYPE "public"."action_events_event_enum" AS ENUM('ADD_ROW', 'UPDATE_ROW', 'DELETE_ROW', 'CUSTOM')`, + ); + await queryRunner.query( + `CREATE TABLE "action_events" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "event" "public"."action_events_event_enum" NOT NULL DEFAULT 'CUSTOM', "title" character varying, "icon" character varying, "table_name" character varying, "created_at" TIMESTAMP, "require_confirmation" boolean NOT NULL DEFAULT false, CONSTRAINT "PK_38b3cd177b610ee89f23bec7ea8" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "rules_events" ("action_rules" uuid NOT NULL, "action_events" uuid NOT NULL, CONSTRAINT "PK_3a51ebca253c2305650ab97a699" PRIMARY KEY ("action_rules", "action_events"))`, + ); + await queryRunner.query(`CREATE INDEX "IDX_5219b43c93dfa03f98eec58e98" ON "rules_events" ("action_rules") `); + await queryRunner.query(`CREATE INDEX "IDX_3f0cd18797ae23deb078612b6d" ON "rules_events" ("action_events") `); + await queryRunner.query(`ALTER TABLE "table_actions" ADD "created_at" TIMESTAMP`); + await queryRunner.query( + `ALTER TABLE "rules_events" ADD CONSTRAINT "FK_5219b43c93dfa03f98eec58e98f" FOREIGN KEY ("action_rules") REFERENCES "action_rules"("id") ON DELETE CASCADE ON UPDATE CASCADE`, + ); + await queryRunner.query( + `ALTER TABLE "rules_events" ADD CONSTRAINT "FK_3f0cd18797ae23deb078612b6dd" FOREIGN KEY ("action_events") REFERENCES "action_events"("id") ON DELETE NO ACTION ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "rules_events" DROP CONSTRAINT "FK_3f0cd18797ae23deb078612b6dd"`); - await queryRunner.query(`ALTER TABLE "rules_events" DROP CONSTRAINT "FK_5219b43c93dfa03f98eec58e98f"`); - await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "created_at"`); - await queryRunner.query(`DROP INDEX "public"."IDX_3f0cd18797ae23deb078612b6d"`); - await queryRunner.query(`DROP INDEX "public"."IDX_5219b43c93dfa03f98eec58e98"`); - await queryRunner.query(`DROP TABLE "rules_events"`); - await queryRunner.query(`DROP TABLE "action_events"`); - await queryRunner.query(`DROP TYPE "public"."action_events_event_enum"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "rules_events" DROP CONSTRAINT "FK_3f0cd18797ae23deb078612b6dd"`); + await queryRunner.query(`ALTER TABLE "rules_events" DROP CONSTRAINT "FK_5219b43c93dfa03f98eec58e98f"`); + await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "created_at"`); + await queryRunner.query(`DROP INDEX "public"."IDX_3f0cd18797ae23deb078612b6d"`); + await queryRunner.query(`DROP INDEX "public"."IDX_5219b43c93dfa03f98eec58e98"`); + await queryRunner.query(`DROP TABLE "rules_events"`); + await queryRunner.query(`DROP TABLE "action_events"`); + await queryRunner.query(`DROP TYPE "public"."action_events_event_enum"`); + } } diff --git a/backend/src/migrations/1719389599034-ReworkTableActionsRemoveRelationBetweenActionsAndConnection.ts b/backend/src/migrations/1719389599034-ReworkTableActionsRemoveRelationBetweenActionsAndConnection.ts index 7e9db74ed..f407b525a 100644 --- a/backend/src/migrations/1719389599034-ReworkTableActionsRemoveRelationBetweenActionsAndConnection.ts +++ b/backend/src/migrations/1719389599034-ReworkTableActionsRemoveRelationBetweenActionsAndConnection.ts @@ -1,21 +1,21 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class ReworkTableActionsRemoveRelationBetweenActionsAndConnection1719389599034 implements MigrationInterface { - name = 'ReworkTableActionsRemoveRelationBetweenActionsAndConnection1719389599034'; + name = 'ReworkTableActionsRemoveRelationBetweenActionsAndConnection1719389599034'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "action_rules" DROP CONSTRAINT "FK_754352f9577b1b87a4593eb6f4c"`); - await queryRunner.query(`ALTER TABLE "action_rules" DROP COLUMN "connectionId"`); - await queryRunner.query(`ALTER TABLE "action_rules" ALTER COLUMN "created_at" SET NOT NULL`); - await queryRunner.query(`ALTER TABLE "action_rules" ALTER COLUMN "created_at" SET DEFAULT now()`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "action_rules" DROP CONSTRAINT "FK_754352f9577b1b87a4593eb6f4c"`); + await queryRunner.query(`ALTER TABLE "action_rules" DROP COLUMN "connectionId"`); + await queryRunner.query(`ALTER TABLE "action_rules" ALTER COLUMN "created_at" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "action_rules" ALTER COLUMN "created_at" SET DEFAULT now()`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "action_rules" ALTER COLUMN "created_at" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "action_rules" ALTER COLUMN "created_at" DROP NOT NULL`); - await queryRunner.query(`ALTER TABLE "action_rules" ADD "connectionId" uuid`); - await queryRunner.query( - `ALTER TABLE "action_rules" ADD CONSTRAINT "FK_754352f9577b1b87a4593eb6f4c" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "action_rules" ALTER COLUMN "created_at" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "action_rules" ALTER COLUMN "created_at" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "action_rules" ADD "connectionId" uuid`); + await queryRunner.query( + `ALTER TABLE "action_rules" ADD CONSTRAINT "FK_754352f9577b1b87a4593eb6f4c" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } } diff --git a/backend/src/migrations/1719404444515-AddDefaultTimestampInTableActionEntity.ts b/backend/src/migrations/1719404444515-AddDefaultTimestampInTableActionEntity.ts index 7e07c7ae0..762b1e80c 100644 --- a/backend/src/migrations/1719404444515-AddDefaultTimestampInTableActionEntity.ts +++ b/backend/src/migrations/1719404444515-AddDefaultTimestampInTableActionEntity.ts @@ -1,16 +1,16 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddDefaultTimestampInTableActionEntity1719404444515 implements MigrationInterface { - name = 'AddDefaultTimestampInTableActionEntity1719404444515'; + name = 'AddDefaultTimestampInTableActionEntity1719404444515'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`UPDATE "table_actions" SET "created_at" = now() WHERE "created_at" IS NULL`); - await queryRunner.query(`ALTER TABLE "table_actions" ALTER COLUMN "created_at" SET NOT NULL`); - await queryRunner.query(`ALTER TABLE "table_actions" ALTER COLUMN "created_at" SET DEFAULT now()`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`UPDATE "table_actions" SET "created_at" = now() WHERE "created_at" IS NULL`); + await queryRunner.query(`ALTER TABLE "table_actions" ALTER COLUMN "created_at" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "table_actions" ALTER COLUMN "created_at" SET DEFAULT now()`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_actions" ALTER COLUMN "created_at" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "table_actions" ALTER COLUMN "created_at" DROP NOT NULL`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_actions" ALTER COLUMN "created_at" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "table_actions" ALTER COLUMN "created_at" DROP NOT NULL`); + } } diff --git a/backend/src/migrations/1719558477807-ChangeRelationsTableActionRuleEvent.ts b/backend/src/migrations/1719558477807-ChangeRelationsTableActionRuleEvent.ts index 828df461a..c54e52e88 100644 --- a/backend/src/migrations/1719558477807-ChangeRelationsTableActionRuleEvent.ts +++ b/backend/src/migrations/1719558477807-ChangeRelationsTableActionRuleEvent.ts @@ -1,23 +1,23 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class ChangeRelationsTableActionRuleEvent1719558477807 implements MigrationInterface { - name = 'ChangeRelationsTableActionRuleEvent1719558477807'; + name = 'ChangeRelationsTableActionRuleEvent1719558477807'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "action_events" ADD "action_rule_id" uuid`); - await queryRunner.query(`ALTER TABLE "table_actions" ADD "action_rule_id" uuid`); - await queryRunner.query( - `ALTER TABLE "action_events" ADD CONSTRAINT "FK_a50c2b0972fa5a305a57d9babc0" FOREIGN KEY ("action_rule_id") REFERENCES "action_rules"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "table_actions" ADD CONSTRAINT "FK_da9e88e07a6949839e8a161ba7d" FOREIGN KEY ("action_rule_id") REFERENCES "action_rules"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "action_events" ADD "action_rule_id" uuid`); + await queryRunner.query(`ALTER TABLE "table_actions" ADD "action_rule_id" uuid`); + await queryRunner.query( + `ALTER TABLE "action_events" ADD CONSTRAINT "FK_a50c2b0972fa5a305a57d9babc0" FOREIGN KEY ("action_rule_id") REFERENCES "action_rules"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "table_actions" ADD CONSTRAINT "FK_da9e88e07a6949839e8a161ba7d" FOREIGN KEY ("action_rule_id") REFERENCES "action_rules"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_actions" DROP CONSTRAINT "FK_da9e88e07a6949839e8a161ba7d"`); - await queryRunner.query(`ALTER TABLE "action_events" DROP CONSTRAINT "FK_a50c2b0972fa5a305a57d9babc0"`); - await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "action_rule_id"`); - await queryRunner.query(`ALTER TABLE "action_events" DROP COLUMN "action_rule_id"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_actions" DROP CONSTRAINT "FK_da9e88e07a6949839e8a161ba7d"`); + await queryRunner.query(`ALTER TABLE "action_events" DROP CONSTRAINT "FK_a50c2b0972fa5a305a57d9babc0"`); + await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "action_rule_id"`); + await queryRunner.query(`ALTER TABLE "action_events" DROP COLUMN "action_rule_id"`); + } } diff --git a/backend/src/migrations/1719565821687-RemoveTableNameFromEventEntity.ts b/backend/src/migrations/1719565821687-RemoveTableNameFromEventEntity.ts index 4b9467aa4..49647cc0f 100644 --- a/backend/src/migrations/1719565821687-RemoveTableNameFromEventEntity.ts +++ b/backend/src/migrations/1719565821687-RemoveTableNameFromEventEntity.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class RemoveTableNameFromEventEntity1719565821687 implements MigrationInterface { - name = 'RemoveTableNameFromEventEntity1719565821687'; + name = 'RemoveTableNameFromEventEntity1719565821687'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "action_events" DROP COLUMN "table_name"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "action_events" DROP COLUMN "table_name"`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "action_events" ADD "table_name" character varying`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "action_events" ADD "table_name" character varying`); + } } diff --git a/backend/src/migrations/1719576179811-AddRelationConnectionEntityActionRulesEntity.ts b/backend/src/migrations/1719576179811-AddRelationConnectionEntityActionRulesEntity.ts index fc8e562b3..4433f8d9e 100644 --- a/backend/src/migrations/1719576179811-AddRelationConnectionEntityActionRulesEntity.ts +++ b/backend/src/migrations/1719576179811-AddRelationConnectionEntityActionRulesEntity.ts @@ -1,17 +1,17 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddRelationConnectionEntityActionRuleEntity1719576179811 implements MigrationInterface { - name = 'AddRelationConnectionEntityActionRuleEntity1719576179811'; + name = 'AddRelationConnectionEntityActionRuleEntity1719576179811'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "action_rules" ADD "connection_id" uuid`); - await queryRunner.query( - `ALTER TABLE "action_rules" ADD CONSTRAINT "FK_b4d9e8aa8bb729005941f4cdbac" FOREIGN KEY ("connection_id") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "action_rules" ADD "connection_id" uuid`); + await queryRunner.query( + `ALTER TABLE "action_rules" ADD CONSTRAINT "FK_b4d9e8aa8bb729005941f4cdbac" FOREIGN KEY ("connection_id") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "action_rules" DROP CONSTRAINT "FK_b4d9e8aa8bb729005941f4cdbac"`); - await queryRunner.query(`ALTER TABLE "action_rules" DROP COLUMN "connection_id"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "action_rules" DROP CONSTRAINT "FK_b4d9e8aa8bb729005941f4cdbac"`); + await queryRunner.query(`ALTER TABLE "action_rules" DROP COLUMN "connection_id"`); + } } diff --git a/backend/src/migrations/1719581021820-AddDefaultTimestampToActionEventEntity.ts b/backend/src/migrations/1719581021820-AddDefaultTimestampToActionEventEntity.ts index 2fe335826..58f966a0e 100644 --- a/backend/src/migrations/1719581021820-AddDefaultTimestampToActionEventEntity.ts +++ b/backend/src/migrations/1719581021820-AddDefaultTimestampToActionEventEntity.ts @@ -1,15 +1,15 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddDefaultTimestampToActionEventEntity1719581021820 implements MigrationInterface { - name = 'AddDefaultTimestampToActionEventEntity1719581021820'; + name = 'AddDefaultTimestampToActionEventEntity1719581021820'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "action_events" ALTER COLUMN "created_at" SET NOT NULL`); - await queryRunner.query(`ALTER TABLE "action_events" ALTER COLUMN "created_at" SET DEFAULT now()`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "action_events" ALTER COLUMN "created_at" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "action_events" ALTER COLUMN "created_at" SET DEFAULT now()`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "action_events" ALTER COLUMN "created_at" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "action_events" ALTER COLUMN "created_at" DROP NOT NULL`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "action_events" ALTER COLUMN "created_at" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "action_events" ALTER COLUMN "created_at" DROP NOT NULL`); + } } diff --git a/backend/src/migrations/1720185441059-AddApiKeyEntity.ts b/backend/src/migrations/1720185441059-AddApiKeyEntity.ts index bbc95bbf2..61058f5d1 100644 --- a/backend/src/migrations/1720185441059-AddApiKeyEntity.ts +++ b/backend/src/migrations/1720185441059-AddApiKeyEntity.ts @@ -1,19 +1,19 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddApiKeyEntity1720185441059 implements MigrationInterface { - name = 'AddApiKeyEntity1720185441059'; + name = 'AddApiKeyEntity1720185441059'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TABLE "user_api_key" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "title" character varying(255) NOT NULL, "hash" character varying NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "userId" uuid, CONSTRAINT "UQ_f25da5419d6477d2550dca5aa8d" UNIQUE ("hash"), CONSTRAINT "PK_9180f9a158e8cda6864358cd462" PRIMARY KEY ("id"))`, - ); - await queryRunner.query( - `ALTER TABLE "user_api_key" ADD CONSTRAINT "FK_c6316cc59f67b45ed31310bce53" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "user_api_key" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "title" character varying(255) NOT NULL, "hash" character varying NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT now(), "userId" uuid, CONSTRAINT "UQ_f25da5419d6477d2550dca5aa8d" UNIQUE ("hash"), CONSTRAINT "PK_9180f9a158e8cda6864358cd462" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "user_api_key" ADD CONSTRAINT "FK_c6316cc59f67b45ed31310bce53" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_api_key" DROP CONSTRAINT "FK_c6316cc59f67b45ed31310bce53"`); - await queryRunner.query(`DROP TABLE "user_api_key"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user_api_key" DROP CONSTRAINT "FK_c6316cc59f67b45ed31310bce53"`); + await queryRunner.query(`DROP TABLE "user_api_key"`); + } } diff --git a/backend/src/migrations/1721310459589-MoveTypePropertyFromActionIntoActionEvent.ts b/backend/src/migrations/1721310459589-MoveTypePropertyFromActionIntoActionEvent.ts index 23d4120fe..463de7cf4 100644 --- a/backend/src/migrations/1721310459589-MoveTypePropertyFromActionIntoActionEvent.ts +++ b/backend/src/migrations/1721310459589-MoveTypePropertyFromActionIntoActionEvent.ts @@ -1,23 +1,23 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class MoveTypePropertyFromActionIntoActionEvent1721310459589 implements MigrationInterface { - name = 'MoveTypePropertyFromActionIntoActionEvent1721310459589'; + name = 'MoveTypePropertyFromActionIntoActionEvent1721310459589'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "type"`); - await queryRunner.query(`DROP TYPE "public"."table_actions_type_enum"`); - await queryRunner.query(`CREATE TYPE "public"."action_events_type_enum" AS ENUM('single', 'multiple')`); - await queryRunner.query( - `ALTER TABLE "action_events" ADD "type" "public"."action_events_type_enum" NOT NULL DEFAULT 'single'`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_actions" DROP COLUMN "type"`); + await queryRunner.query(`DROP TYPE "public"."table_actions_type_enum"`); + await queryRunner.query(`CREATE TYPE "public"."action_events_type_enum" AS ENUM('single', 'multiple')`); + await queryRunner.query( + `ALTER TABLE "action_events" ADD "type" "public"."action_events_type_enum" NOT NULL DEFAULT 'single'`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "action_events" DROP COLUMN "type"`); - await queryRunner.query(`DROP TYPE "public"."action_events_type_enum"`); - await queryRunner.query(`CREATE TYPE "public"."table_actions_type_enum" AS ENUM('single', 'multiple')`); - await queryRunner.query( - `ALTER TABLE "table_actions" ADD "type" "public"."table_actions_type_enum" NOT NULL DEFAULT 'single'`, - ); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "action_events" DROP COLUMN "type"`); + await queryRunner.query(`DROP TYPE "public"."action_events_type_enum"`); + await queryRunner.query(`CREATE TYPE "public"."table_actions_type_enum" AS ENUM('single', 'multiple')`); + await queryRunner.query( + `ALTER TABLE "table_actions" ADD "type" "public"."table_actions_type_enum" NOT NULL DEFAULT 'single'`, + ); + } } diff --git a/backend/src/migrations/1723208278859-ChangeIdStrategyInConnectionEntity.ts b/backend/src/migrations/1723208278859-ChangeIdStrategyInConnectionEntity.ts index 4abbf28c3..61f545138 100644 --- a/backend/src/migrations/1723208278859-ChangeIdStrategyInConnectionEntity.ts +++ b/backend/src/migrations/1723208278859-ChangeIdStrategyInConnectionEntity.ts @@ -1,210 +1,210 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class ChangeIdStrategyInConnectionEntity1723208278859 implements MigrationInterface { - name = 'ChangeIdStrategyInConnectionEntity1723208278859'; - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "agent" ADD "temp_connectionId" character varying(38)`); - await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "temp_connectionId" character varying(38)`); - await queryRunner.query(`ALTER TABLE "group" ADD "temp_connectionId" character varying(38)`); - await queryRunner.query(`ALTER TABLE "table_info" ADD "temp_connectionId" character varying(38)`); - await queryRunner.query(`ALTER TABLE "tableLogs" ADD "temp_connectionIdId" character varying(38)`); - await queryRunner.query(`ALTER TABLE "action_rules" ADD "temp_connection_id" character varying(38)`); - await queryRunner.query(`ALTER TABLE "tableSettings" ADD "temp_connectionIdId" character varying(38)`); - - await queryRunner.query(`UPDATE "agent" SET "temp_connectionId" = "connectionId"`); - await queryRunner.query(`UPDATE "connectionProperties" SET "temp_connectionId" = "connectionId"`); - await queryRunner.query(`UPDATE "group" SET "temp_connectionId" = "connectionId"`); - await queryRunner.query(`UPDATE "table_info" SET "temp_connectionId" = "connectionId"`); - await queryRunner.query(`UPDATE "tableLogs" SET "temp_connectionIdId" = "connectionIdId"`); - await queryRunner.query(`UPDATE "action_rules" SET "temp_connection_id" = "connection_id"`); - await queryRunner.query(`UPDATE "tableSettings" SET "temp_connectionIdId" = "connectionIdId"`); - - await queryRunner.query(`ALTER TABLE "agent" DROP CONSTRAINT "FK_5fa2f66b3adc27993e59ce043e5"`); - await queryRunner.query(`ALTER TABLE "agent" DROP CONSTRAINT "REL_5fa2f66b3adc27993e59ce043e"`); - await queryRunner.query(`ALTER TABLE "agent" DROP COLUMN "connectionId"`); - await queryRunner.query(`ALTER TABLE "agent" ADD "connectionId" character varying(38)`); - - await queryRunner.query(`ALTER TABLE "connectionProperties" DROP CONSTRAINT "FK_4c4090f071716a2333a2d5c52ca"`); - await queryRunner.query(`ALTER TABLE "connectionProperties" DROP CONSTRAINT "REL_4c4090f071716a2333a2d5c52c"`); - await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "connectionId"`); - await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "connectionId" character varying(38)`); - - await queryRunner.query(`ALTER TABLE "group" DROP CONSTRAINT "FK_fad2f67fd9597d6b81b401f2fa3"`); - await queryRunner.query(`ALTER TABLE "group" DROP CONSTRAINT "UQ_c5dcbf6b8ecf068f959a367dc9e"`); - await queryRunner.query(`ALTER TABLE "group" DROP COLUMN "connectionId"`); - await queryRunner.query(`ALTER TABLE "group" ADD "connectionId" character varying(38)`); - - await queryRunner.query(`ALTER TABLE "table_info" DROP CONSTRAINT "FK_0b9cf14b1a4c562a84eae8f70f2"`); - await queryRunner.query(`ALTER TABLE "table_info" DROP COLUMN "connectionId"`); - await queryRunner.query(`ALTER TABLE "table_info" ADD "connectionId" character varying(38)`); - - await queryRunner.query(`ALTER TABLE "tableLogs" DROP CONSTRAINT "FK_a5dd6c8c66dd42f16aa72b3afd3"`); - await queryRunner.query(`ALTER TABLE "tableLogs" DROP COLUMN "connectionIdId"`); - await queryRunner.query(`ALTER TABLE "tableLogs" ADD "connectionIdId" character varying(38)`); - - await queryRunner.query(`ALTER TABLE "action_rules" DROP CONSTRAINT "FK_b4d9e8aa8bb729005941f4cdbac"`); - await queryRunner.query(`ALTER TABLE "action_rules" DROP COLUMN "connection_id"`); - await queryRunner.query(`ALTER TABLE "action_rules" ADD "connection_id" character varying(38)`); - - await queryRunner.query(`ALTER TABLE "tableSettings" DROP CONSTRAINT "FK_e959bd443a42403e4a76dcdcbef"`); - await queryRunner.query(`ALTER TABLE "tableSettings" DROP CONSTRAINT "UQ_5a62e8aec5c74174d8355c34b70"`); - await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "connectionIdId"`); - await queryRunner.query(`ALTER TABLE "tableSettings" ADD "connectionIdId" character varying(38)`); - - await queryRunner.query(`ALTER TABLE "table_triggers" DROP CONSTRAINT "FK_937487c7a49aefc776beb196f42"`); - - await queryRunner.query(`ALTER TABLE "connection" ADD COLUMN "temp_id" varchar(38)`); - await queryRunner.query(`UPDATE "connection" SET "temp_id" = "id"::text`); - await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "PK_be611ce8b8cf439091c82a334b2"`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "id" TYPE varchar(38)`); - await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "id" DROP DEFAULT`); - await queryRunner.query(`UPDATE "connection" SET "id" = "temp_id"`); - await queryRunner.query( - `ALTER TABLE "connection" ADD CONSTRAINT "PK_be611ce8b8cf439091c82a334b2" PRIMARY KEY ("id")`, - ); - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "temp_id"`); - - await queryRunner.query(`UPDATE "agent" SET "connectionId" = "temp_connectionId"`); - await queryRunner.query(`UPDATE "connectionProperties" SET "connectionId" = "temp_connectionId"`); - await queryRunner.query(`UPDATE "group" SET "connectionId" = "temp_connectionId"`); - await queryRunner.query(`UPDATE "table_info" SET "connectionId" = "temp_connectionId"`); - await queryRunner.query(`UPDATE "tableLogs" SET "connectionIdId" = "temp_connectionIdId"`); - await queryRunner.query(`UPDATE "action_rules" SET "connection_id" = "temp_connection_id"`); - await queryRunner.query(`UPDATE "tableSettings" SET "connectionIdId" = "temp_connectionIdId"`); - - await queryRunner.query(`ALTER TABLE "agent" DROP COLUMN "temp_connectionId"`); - await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "temp_connectionId"`); - await queryRunner.query(`ALTER TABLE "group" DROP COLUMN "temp_connectionId"`); - await queryRunner.query(`ALTER TABLE "table_info" DROP COLUMN "temp_connectionId"`); - await queryRunner.query(`ALTER TABLE "tableLogs" DROP COLUMN "temp_connectionIdId"`); - await queryRunner.query(`ALTER TABLE "action_rules" DROP COLUMN "temp_connection_id"`); - await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "temp_connectionIdId"`); - - await queryRunner.query( - `ALTER TABLE "group" ADD CONSTRAINT "UQ_c5dcbf6b8ecf068f959a367dc9e" UNIQUE ("connectionId", "title")`, - ); - await queryRunner.query( - `ALTER TABLE "tableSettings" ADD CONSTRAINT "UQ_5a62e8aec5c74174d8355c34b70" UNIQUE ("connectionIdId", "table_name")`, - ); - await queryRunner.query( - `ALTER TABLE "agent" ADD CONSTRAINT "FK_5fa2f66b3adc27993e59ce043e5" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "connectionProperties" ADD CONSTRAINT "FK_4c4090f071716a2333a2d5c52ca" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "group" ADD CONSTRAINT "FK_fad2f67fd9597d6b81b401f2fa3" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "table_info" ADD CONSTRAINT "FK_0b9cf14b1a4c562a84eae8f70f2" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "tableLogs" ADD CONSTRAINT "FK_a5dd6c8c66dd42f16aa72b3afd3" FOREIGN KEY ("connectionIdId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "action_rules" ADD CONSTRAINT "FK_b4d9e8aa8bb729005941f4cdbac" FOREIGN KEY ("connection_id") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "tableSettings" ADD CONSTRAINT "FK_e959bd443a42403e4a76dcdcbef" FOREIGN KEY ("connectionIdId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "agent" ADD CONSTRAINT "UQ_5fa2f66b3adc27993e59ce043e5" UNIQUE ("connectionId")`, - ); - await queryRunner.query( - `ALTER TABLE "connectionProperties" ADD CONSTRAINT "UQ_4c4090f071716a2333a2d5c52ca" UNIQUE ("connectionId")`, - ); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connectionProperties" DROP CONSTRAINT "UQ_4c4090f071716a2333a2d5c52ca"`); - await queryRunner.query(`ALTER TABLE "agent" DROP CONSTRAINT "UQ_5fa2f66b3adc27993e59ce043e5"`); - - await queryRunner.query(`ALTER TABLE "tableSettings" DROP CONSTRAINT "FK_e959bd443a42403e4a76dcdcbef"`); - await queryRunner.query(`ALTER TABLE "action_rules" DROP CONSTRAINT "FK_b4d9e8aa8bb729005941f4cdbac"`); - await queryRunner.query(`ALTER TABLE "tableLogs" DROP CONSTRAINT "FK_a5dd6c8c66dd42f16aa72b3afd3"`); - await queryRunner.query(`ALTER TABLE "table_info" DROP CONSTRAINT "FK_0b9cf14b1a4c562a84eae8f70f2"`); - await queryRunner.query(`ALTER TABLE "group" DROP CONSTRAINT "FK_fad2f67fd9597d6b81b401f2fa3"`); - await queryRunner.query(`ALTER TABLE "connectionProperties" DROP CONSTRAINT "FK_4c4090f071716a2333a2d5c52ca"`); - await queryRunner.query(`ALTER TABLE "agent" DROP CONSTRAINT "FK_5fa2f66b3adc27993e59ce043e5"`); - - await queryRunner.query(`ALTER TABLE "tableSettings" ADD "temp_connectionIdId" uuid`); - await queryRunner.query(`UPDATE "tableSettings" SET "temp_connectionIdId" = "connectionIdId"`); - await queryRunner.query(`ALTER TABLE "action_rules" ADD "temp_connection_id" uuid`); - await queryRunner.query(`UPDATE "action_rules" SET "temp_connection_id" = "connection_id"`); - await queryRunner.query(`ALTER TABLE "tableLogs" ADD "temp_connectionIdId" uuid`); - await queryRunner.query(`UPDATE "tableLogs" SET "temp_connectionIdId" = "connectionIdId"`); - await queryRunner.query(`ALTER TABLE "table_info" ADD "temp_connectionId" uuid`); - await queryRunner.query(`UPDATE "table_info" SET "temp_connectionId" = "connectionId"`); - await queryRunner.query(`ALTER TABLE "group" ADD "temp_connectionId" uuid`); - await queryRunner.query(`UPDATE "group" SET "temp_connectionId" = "connectionId"`); - await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "temp_connectionId" uuid`); - await queryRunner.query(`UPDATE "connectionProperties" SET "temp_connectionId" = "connectionId"`); - await queryRunner.query(`ALTER TABLE "agent" ADD "temp_connectionId" uuid`); - await queryRunner.query(`UPDATE "agent" SET "temp_connectionId" = "connectionId"`); - - await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "connectionIdId"`); - await queryRunner.query(`ALTER TABLE "tableSettings" ADD "connectionIdId" uuid`); - await queryRunner.query(`UPDATE "tableSettings" SET "connectionIdId" = "temp_connectionIdId"`); - await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "temp_connectionIdId"`); - - await queryRunner.query(`ALTER TABLE "action_rules" DROP COLUMN "connection_id"`); - await queryRunner.query(`ALTER TABLE "action_rules" ADD "connection_id" uuid`); - await queryRunner.query(`UPDATE "action_rules" SET "connection_id" = "temp_connection_id"`); - await queryRunner.query(`ALTER TABLE "action_rules" DROP COLUMN "temp_connection_id"`); - - await queryRunner.query(`ALTER TABLE "tableLogs" DROP COLUMN "connectionIdId"`); - await queryRunner.query(`ALTER TABLE "tableLogs" ADD "connectionIdId" uuid`); - await queryRunner.query(`UPDATE "tableLogs" SET "connectionIdId" = "temp_connectionIdId"`); - await queryRunner.query(`ALTER TABLE "tableLogs" DROP COLUMN "temp_connectionIdId"`); - - await queryRunner.query(`ALTER TABLE "table_info" DROP COLUMN "connectionId"`); - await queryRunner.query(`ALTER TABLE "table_info" ADD "connectionId" uuid`); - await queryRunner.query(`UPDATE "table_info" SET "connectionId" = "temp_connectionId"`); - await queryRunner.query(`ALTER TABLE "table_info" DROP COLUMN "temp_connectionId"`); - - await queryRunner.query(`ALTER TABLE "group" DROP COLUMN "connectionId"`); - await queryRunner.query(`ALTER TABLE "group" ADD "connectionId" uuid`); - await queryRunner.query(`UPDATE "group" SET "connectionId" = "temp_connectionId"`); - await queryRunner.query(`ALTER TABLE "group" DROP COLUMN "temp_connectionId"`); - - await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "connectionId"`); - await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "connectionId" uuid`); - await queryRunner.query(`UPDATE "connectionProperties" SET "connectionId" = "temp_connectionId"`); - await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "temp_connectionId"`); - - await queryRunner.query(`ALTER TABLE "agent" DROP COLUMN "connectionId"`); - await queryRunner.query(`ALTER TABLE "agent" ADD "connectionId" uuid`); - await queryRunner.query(`UPDATE "agent" SET "connectionId" = "temp_connectionId"`); - await queryRunner.query(`ALTER TABLE "agent" DROP COLUMN "temp_connectionId"`); - - await queryRunner.query( - `ALTER TABLE "agent" ADD CONSTRAINT "FK_5fa2f66b3adc27993e59ce043e5" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "connectionProperties" ADD CONSTRAINT "FK_4c4090f071716a2333a2d5c52ca" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "group" ADD CONSTRAINT "FK_fad2f67fd9597d6b81b401f2fa3" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "table_info" ADD CONSTRAINT "FK_0b9cf14b1a4c562a84eae8f70f2" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "tableLogs" ADD CONSTRAINT "FK_a5dd6c8c66dd42f16aa72b3afd3" FOREIGN KEY ("connectionIdId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "action_rules" ADD CONSTRAINT "FK_b4d9e8aa8bb729005941f4cdbac" FOREIGN KEY ("connection_id") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "tableSettings" ADD CONSTRAINT "FK_e959bd443a42403e4a76dcdcbef" FOREIGN KEY ("connectionIdId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - - await queryRunner.query( - `ALTER TABLE "agent" ADD CONSTRAINT "UQ_5fa2f66b3adc27993e59ce043e5" UNIQUE ("connectionId")`, - ); - await queryRunner.query( - `ALTER TABLE "connectionProperties" ADD CONSTRAINT "UQ_4c4090f071716a2333a2d5c52ca" UNIQUE ("connectionId")`, - ); - } + name = 'ChangeIdStrategyInConnectionEntity1723208278859'; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "agent" ADD "temp_connectionId" character varying(38)`); + await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "temp_connectionId" character varying(38)`); + await queryRunner.query(`ALTER TABLE "group" ADD "temp_connectionId" character varying(38)`); + await queryRunner.query(`ALTER TABLE "table_info" ADD "temp_connectionId" character varying(38)`); + await queryRunner.query(`ALTER TABLE "tableLogs" ADD "temp_connectionIdId" character varying(38)`); + await queryRunner.query(`ALTER TABLE "action_rules" ADD "temp_connection_id" character varying(38)`); + await queryRunner.query(`ALTER TABLE "tableSettings" ADD "temp_connectionIdId" character varying(38)`); + + await queryRunner.query(`UPDATE "agent" SET "temp_connectionId" = "connectionId"`); + await queryRunner.query(`UPDATE "connectionProperties" SET "temp_connectionId" = "connectionId"`); + await queryRunner.query(`UPDATE "group" SET "temp_connectionId" = "connectionId"`); + await queryRunner.query(`UPDATE "table_info" SET "temp_connectionId" = "connectionId"`); + await queryRunner.query(`UPDATE "tableLogs" SET "temp_connectionIdId" = "connectionIdId"`); + await queryRunner.query(`UPDATE "action_rules" SET "temp_connection_id" = "connection_id"`); + await queryRunner.query(`UPDATE "tableSettings" SET "temp_connectionIdId" = "connectionIdId"`); + + await queryRunner.query(`ALTER TABLE "agent" DROP CONSTRAINT "FK_5fa2f66b3adc27993e59ce043e5"`); + await queryRunner.query(`ALTER TABLE "agent" DROP CONSTRAINT "REL_5fa2f66b3adc27993e59ce043e"`); + await queryRunner.query(`ALTER TABLE "agent" DROP COLUMN "connectionId"`); + await queryRunner.query(`ALTER TABLE "agent" ADD "connectionId" character varying(38)`); + + await queryRunner.query(`ALTER TABLE "connectionProperties" DROP CONSTRAINT "FK_4c4090f071716a2333a2d5c52ca"`); + await queryRunner.query(`ALTER TABLE "connectionProperties" DROP CONSTRAINT "REL_4c4090f071716a2333a2d5c52c"`); + await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "connectionId"`); + await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "connectionId" character varying(38)`); + + await queryRunner.query(`ALTER TABLE "group" DROP CONSTRAINT "FK_fad2f67fd9597d6b81b401f2fa3"`); + await queryRunner.query(`ALTER TABLE "group" DROP CONSTRAINT "UQ_c5dcbf6b8ecf068f959a367dc9e"`); + await queryRunner.query(`ALTER TABLE "group" DROP COLUMN "connectionId"`); + await queryRunner.query(`ALTER TABLE "group" ADD "connectionId" character varying(38)`); + + await queryRunner.query(`ALTER TABLE "table_info" DROP CONSTRAINT "FK_0b9cf14b1a4c562a84eae8f70f2"`); + await queryRunner.query(`ALTER TABLE "table_info" DROP COLUMN "connectionId"`); + await queryRunner.query(`ALTER TABLE "table_info" ADD "connectionId" character varying(38)`); + + await queryRunner.query(`ALTER TABLE "tableLogs" DROP CONSTRAINT "FK_a5dd6c8c66dd42f16aa72b3afd3"`); + await queryRunner.query(`ALTER TABLE "tableLogs" DROP COLUMN "connectionIdId"`); + await queryRunner.query(`ALTER TABLE "tableLogs" ADD "connectionIdId" character varying(38)`); + + await queryRunner.query(`ALTER TABLE "action_rules" DROP CONSTRAINT "FK_b4d9e8aa8bb729005941f4cdbac"`); + await queryRunner.query(`ALTER TABLE "action_rules" DROP COLUMN "connection_id"`); + await queryRunner.query(`ALTER TABLE "action_rules" ADD "connection_id" character varying(38)`); + + await queryRunner.query(`ALTER TABLE "tableSettings" DROP CONSTRAINT "FK_e959bd443a42403e4a76dcdcbef"`); + await queryRunner.query(`ALTER TABLE "tableSettings" DROP CONSTRAINT "UQ_5a62e8aec5c74174d8355c34b70"`); + await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "connectionIdId"`); + await queryRunner.query(`ALTER TABLE "tableSettings" ADD "connectionIdId" character varying(38)`); + + await queryRunner.query(`ALTER TABLE "table_triggers" DROP CONSTRAINT "FK_937487c7a49aefc776beb196f42"`); + + await queryRunner.query(`ALTER TABLE "connection" ADD COLUMN "temp_id" varchar(38)`); + await queryRunner.query(`UPDATE "connection" SET "temp_id" = "id"::text`); + await queryRunner.query(`ALTER TABLE "connection" DROP CONSTRAINT "PK_be611ce8b8cf439091c82a334b2"`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "id" TYPE varchar(38)`); + await queryRunner.query(`ALTER TABLE "connection" ALTER COLUMN "id" DROP DEFAULT`); + await queryRunner.query(`UPDATE "connection" SET "id" = "temp_id"`); + await queryRunner.query( + `ALTER TABLE "connection" ADD CONSTRAINT "PK_be611ce8b8cf439091c82a334b2" PRIMARY KEY ("id")`, + ); + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "temp_id"`); + + await queryRunner.query(`UPDATE "agent" SET "connectionId" = "temp_connectionId"`); + await queryRunner.query(`UPDATE "connectionProperties" SET "connectionId" = "temp_connectionId"`); + await queryRunner.query(`UPDATE "group" SET "connectionId" = "temp_connectionId"`); + await queryRunner.query(`UPDATE "table_info" SET "connectionId" = "temp_connectionId"`); + await queryRunner.query(`UPDATE "tableLogs" SET "connectionIdId" = "temp_connectionIdId"`); + await queryRunner.query(`UPDATE "action_rules" SET "connection_id" = "temp_connection_id"`); + await queryRunner.query(`UPDATE "tableSettings" SET "connectionIdId" = "temp_connectionIdId"`); + + await queryRunner.query(`ALTER TABLE "agent" DROP COLUMN "temp_connectionId"`); + await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "temp_connectionId"`); + await queryRunner.query(`ALTER TABLE "group" DROP COLUMN "temp_connectionId"`); + await queryRunner.query(`ALTER TABLE "table_info" DROP COLUMN "temp_connectionId"`); + await queryRunner.query(`ALTER TABLE "tableLogs" DROP COLUMN "temp_connectionIdId"`); + await queryRunner.query(`ALTER TABLE "action_rules" DROP COLUMN "temp_connection_id"`); + await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "temp_connectionIdId"`); + + await queryRunner.query( + `ALTER TABLE "group" ADD CONSTRAINT "UQ_c5dcbf6b8ecf068f959a367dc9e" UNIQUE ("connectionId", "title")`, + ); + await queryRunner.query( + `ALTER TABLE "tableSettings" ADD CONSTRAINT "UQ_5a62e8aec5c74174d8355c34b70" UNIQUE ("connectionIdId", "table_name")`, + ); + await queryRunner.query( + `ALTER TABLE "agent" ADD CONSTRAINT "FK_5fa2f66b3adc27993e59ce043e5" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "connectionProperties" ADD CONSTRAINT "FK_4c4090f071716a2333a2d5c52ca" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "group" ADD CONSTRAINT "FK_fad2f67fd9597d6b81b401f2fa3" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "table_info" ADD CONSTRAINT "FK_0b9cf14b1a4c562a84eae8f70f2" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "tableLogs" ADD CONSTRAINT "FK_a5dd6c8c66dd42f16aa72b3afd3" FOREIGN KEY ("connectionIdId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "action_rules" ADD CONSTRAINT "FK_b4d9e8aa8bb729005941f4cdbac" FOREIGN KEY ("connection_id") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "tableSettings" ADD CONSTRAINT "FK_e959bd443a42403e4a76dcdcbef" FOREIGN KEY ("connectionIdId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "agent" ADD CONSTRAINT "UQ_5fa2f66b3adc27993e59ce043e5" UNIQUE ("connectionId")`, + ); + await queryRunner.query( + `ALTER TABLE "connectionProperties" ADD CONSTRAINT "UQ_4c4090f071716a2333a2d5c52ca" UNIQUE ("connectionId")`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connectionProperties" DROP CONSTRAINT "UQ_4c4090f071716a2333a2d5c52ca"`); + await queryRunner.query(`ALTER TABLE "agent" DROP CONSTRAINT "UQ_5fa2f66b3adc27993e59ce043e5"`); + + await queryRunner.query(`ALTER TABLE "tableSettings" DROP CONSTRAINT "FK_e959bd443a42403e4a76dcdcbef"`); + await queryRunner.query(`ALTER TABLE "action_rules" DROP CONSTRAINT "FK_b4d9e8aa8bb729005941f4cdbac"`); + await queryRunner.query(`ALTER TABLE "tableLogs" DROP CONSTRAINT "FK_a5dd6c8c66dd42f16aa72b3afd3"`); + await queryRunner.query(`ALTER TABLE "table_info" DROP CONSTRAINT "FK_0b9cf14b1a4c562a84eae8f70f2"`); + await queryRunner.query(`ALTER TABLE "group" DROP CONSTRAINT "FK_fad2f67fd9597d6b81b401f2fa3"`); + await queryRunner.query(`ALTER TABLE "connectionProperties" DROP CONSTRAINT "FK_4c4090f071716a2333a2d5c52ca"`); + await queryRunner.query(`ALTER TABLE "agent" DROP CONSTRAINT "FK_5fa2f66b3adc27993e59ce043e5"`); + + await queryRunner.query(`ALTER TABLE "tableSettings" ADD "temp_connectionIdId" uuid`); + await queryRunner.query(`UPDATE "tableSettings" SET "temp_connectionIdId" = "connectionIdId"`); + await queryRunner.query(`ALTER TABLE "action_rules" ADD "temp_connection_id" uuid`); + await queryRunner.query(`UPDATE "action_rules" SET "temp_connection_id" = "connection_id"`); + await queryRunner.query(`ALTER TABLE "tableLogs" ADD "temp_connectionIdId" uuid`); + await queryRunner.query(`UPDATE "tableLogs" SET "temp_connectionIdId" = "connectionIdId"`); + await queryRunner.query(`ALTER TABLE "table_info" ADD "temp_connectionId" uuid`); + await queryRunner.query(`UPDATE "table_info" SET "temp_connectionId" = "connectionId"`); + await queryRunner.query(`ALTER TABLE "group" ADD "temp_connectionId" uuid`); + await queryRunner.query(`UPDATE "group" SET "temp_connectionId" = "connectionId"`); + await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "temp_connectionId" uuid`); + await queryRunner.query(`UPDATE "connectionProperties" SET "temp_connectionId" = "connectionId"`); + await queryRunner.query(`ALTER TABLE "agent" ADD "temp_connectionId" uuid`); + await queryRunner.query(`UPDATE "agent" SET "temp_connectionId" = "connectionId"`); + + await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "connectionIdId"`); + await queryRunner.query(`ALTER TABLE "tableSettings" ADD "connectionIdId" uuid`); + await queryRunner.query(`UPDATE "tableSettings" SET "connectionIdId" = "temp_connectionIdId"`); + await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "temp_connectionIdId"`); + + await queryRunner.query(`ALTER TABLE "action_rules" DROP COLUMN "connection_id"`); + await queryRunner.query(`ALTER TABLE "action_rules" ADD "connection_id" uuid`); + await queryRunner.query(`UPDATE "action_rules" SET "connection_id" = "temp_connection_id"`); + await queryRunner.query(`ALTER TABLE "action_rules" DROP COLUMN "temp_connection_id"`); + + await queryRunner.query(`ALTER TABLE "tableLogs" DROP COLUMN "connectionIdId"`); + await queryRunner.query(`ALTER TABLE "tableLogs" ADD "connectionIdId" uuid`); + await queryRunner.query(`UPDATE "tableLogs" SET "connectionIdId" = "temp_connectionIdId"`); + await queryRunner.query(`ALTER TABLE "tableLogs" DROP COLUMN "temp_connectionIdId"`); + + await queryRunner.query(`ALTER TABLE "table_info" DROP COLUMN "connectionId"`); + await queryRunner.query(`ALTER TABLE "table_info" ADD "connectionId" uuid`); + await queryRunner.query(`UPDATE "table_info" SET "connectionId" = "temp_connectionId"`); + await queryRunner.query(`ALTER TABLE "table_info" DROP COLUMN "temp_connectionId"`); + + await queryRunner.query(`ALTER TABLE "group" DROP COLUMN "connectionId"`); + await queryRunner.query(`ALTER TABLE "group" ADD "connectionId" uuid`); + await queryRunner.query(`UPDATE "group" SET "connectionId" = "temp_connectionId"`); + await queryRunner.query(`ALTER TABLE "group" DROP COLUMN "temp_connectionId"`); + + await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "connectionId"`); + await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "connectionId" uuid`); + await queryRunner.query(`UPDATE "connectionProperties" SET "connectionId" = "temp_connectionId"`); + await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "temp_connectionId"`); + + await queryRunner.query(`ALTER TABLE "agent" DROP COLUMN "connectionId"`); + await queryRunner.query(`ALTER TABLE "agent" ADD "connectionId" uuid`); + await queryRunner.query(`UPDATE "agent" SET "connectionId" = "temp_connectionId"`); + await queryRunner.query(`ALTER TABLE "agent" DROP COLUMN "temp_connectionId"`); + + await queryRunner.query( + `ALTER TABLE "agent" ADD CONSTRAINT "FK_5fa2f66b3adc27993e59ce043e5" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "connectionProperties" ADD CONSTRAINT "FK_4c4090f071716a2333a2d5c52ca" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "group" ADD CONSTRAINT "FK_fad2f67fd9597d6b81b401f2fa3" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "table_info" ADD CONSTRAINT "FK_0b9cf14b1a4c562a84eae8f70f2" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "tableLogs" ADD CONSTRAINT "FK_a5dd6c8c66dd42f16aa72b3afd3" FOREIGN KEY ("connectionIdId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "action_rules" ADD CONSTRAINT "FK_b4d9e8aa8bb729005941f4cdbac" FOREIGN KEY ("connection_id") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "tableSettings" ADD CONSTRAINT "FK_e959bd443a42403e4a76dcdcbef" FOREIGN KEY ("connectionIdId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + + await queryRunner.query( + `ALTER TABLE "agent" ADD CONSTRAINT "UQ_5fa2f66b3adc27993e59ce043e5" UNIQUE ("connectionId")`, + ); + await queryRunner.query( + `ALTER TABLE "connectionProperties" ADD CONSTRAINT "UQ_4c4090f071716a2333a2d5c52ca" UNIQUE ("connectionId")`, + ); + } } diff --git a/backend/src/migrations/1725359728220-AddAffectedPrimaryKeyInTableLogsEntity.ts b/backend/src/migrations/1725359728220-AddAffectedPrimaryKeyInTableLogsEntity.ts index 5c92b30e2..27cf3a23c 100644 --- a/backend/src/migrations/1725359728220-AddAffectedPrimaryKeyInTableLogsEntity.ts +++ b/backend/src/migrations/1725359728220-AddAffectedPrimaryKeyInTableLogsEntity.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddAffectedPrimaryKeyInTableLogsEntity1725359728220 implements MigrationInterface { - name = 'AddAffectedPrimaryKeyInTableLogsEntity1725359728220'; + name = 'AddAffectedPrimaryKeyInTableLogsEntity1725359728220'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableLogs" ADD "affected_primary_key" character varying`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableLogs" ADD "affected_primary_key" character varying`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "tableLogs" DROP COLUMN "affected_primary_key"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "tableLogs" DROP COLUMN "affected_primary_key"`); + } } diff --git a/backend/src/migrations/1726057182961-AddShowTestConnectionsPropertyToUserEntity.ts b/backend/src/migrations/1726057182961-AddShowTestConnectionsPropertyToUserEntity.ts index 87dc95d1d..cc5af263b 100644 --- a/backend/src/migrations/1726057182961-AddShowTestConnectionsPropertyToUserEntity.ts +++ b/backend/src/migrations/1726057182961-AddShowTestConnectionsPropertyToUserEntity.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddShowTestConnectionsPropertyToUserEntity1726057182961 implements MigrationInterface { - name = 'AddShowTestConnectionsPropertyToUserEntity1726057182961'; + name = 'AddShowTestConnectionsPropertyToUserEntity1726057182961'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" ADD "showTestConnections" boolean NOT NULL DEFAULT true`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" ADD "showTestConnections" boolean NOT NULL DEFAULT true`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "showTestConnections"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "showTestConnections"`); + } } diff --git a/backend/src/migrations/1731059421635-AddHumanReadebleOptionInConnectionPropertiesEntity.ts b/backend/src/migrations/1731059421635-AddHumanReadebleOptionInConnectionPropertiesEntity.ts index 69a48a7f7..992bae7e6 100644 --- a/backend/src/migrations/1731059421635-AddHumanReadebleOptionInConnectionPropertiesEntity.ts +++ b/backend/src/migrations/1731059421635-AddHumanReadebleOptionInConnectionPropertiesEntity.ts @@ -1,15 +1,15 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddHumanReadebleOptionInConnectionPropertiesEntity1731059421635 implements MigrationInterface { - name = 'AddHumanReadebleOptionInConnectionPropertiesEntity1731059421635'; + name = 'AddHumanReadebleOptionInConnectionPropertiesEntity1731059421635'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `ALTER TABLE "connectionProperties" ADD "human_readable_table_names" boolean NOT NULL DEFAULT true`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "connectionProperties" ADD "human_readable_table_names" boolean NOT NULL DEFAULT true`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "human_readable_table_names"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "human_readable_table_names"`); + } } diff --git a/backend/src/migrations/1731073063525-AddMasterHashPropertyInConnectionEntity.ts b/backend/src/migrations/1731073063525-AddMasterHashPropertyInConnectionEntity.ts index 3d07918f8..faddc5615 100644 --- a/backend/src/migrations/1731073063525-AddMasterHashPropertyInConnectionEntity.ts +++ b/backend/src/migrations/1731073063525-AddMasterHashPropertyInConnectionEntity.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddMasterHashPropertyInConnectionEntity1731073063525 implements MigrationInterface { - name = 'AddMasterHashPropertyInConnectionEntity1731073063525'; + name = 'AddMasterHashPropertyInConnectionEntity1731073063525'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" ADD "master_hash" character varying`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" ADD "master_hash" character varying`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "master_hash"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "master_hash"`); + } } diff --git a/backend/src/migrations/1732893339341-AddAllowAiRequestsPropertyToConnectionProperties.ts b/backend/src/migrations/1732893339341-AddAllowAiRequestsPropertyToConnectionProperties.ts index 013846312..5791e97fa 100644 --- a/backend/src/migrations/1732893339341-AddAllowAiRequestsPropertyToConnectionProperties.ts +++ b/backend/src/migrations/1732893339341-AddAllowAiRequestsPropertyToConnectionProperties.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddAllowAiRequestsPropertyToConnectionProperties1732893339341 implements MigrationInterface { - name = 'AddAllowAiRequestsPropertyToConnectionProperties1732893339341'; + name = 'AddAllowAiRequestsPropertyToConnectionProperties1732893339341'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "allow_ai_requests" boolean NOT NULL DEFAULT true`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "allow_ai_requests" boolean NOT NULL DEFAULT true`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "allow_ai_requests"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "allow_ai_requests"`); + } } diff --git a/backend/src/migrations/1734344160864-AddAiThreadAndAiFileEntities.ts b/backend/src/migrations/1734344160864-AddAiThreadAndAiFileEntities.ts index 4c2f208d8..cd217cd12 100644 --- a/backend/src/migrations/1734344160864-AddAiThreadAndAiFileEntities.ts +++ b/backend/src/migrations/1734344160864-AddAiThreadAndAiFileEntities.ts @@ -1,27 +1,27 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddAiThreadAndAiFileEntities1734344160864 implements MigrationInterface { - name = 'AddAiThreadAndAiFileEntities1734344160864'; + name = 'AddAiThreadAndAiFileEntities1734344160864'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TABLE "ai_user_files" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "file_ai_id" character varying(128) NOT NULL, "threadId" uuid, CONSTRAINT "REL_0cfe8c83471aacc78bb6bf0d99" UNIQUE ("threadId"), CONSTRAINT "PK_cad85eaa0e7888a70c543aea5ad" PRIMARY KEY ("id"))`, - ); - await queryRunner.query( - `CREATE TABLE "ai_user_threads" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "thread_ai_id" character varying(128) NOT NULL, "userId" uuid, CONSTRAINT "PK_456c9992092ab18f4281ba54fd5" PRIMARY KEY ("id"))`, - ); - await queryRunner.query( - `ALTER TABLE "ai_user_files" ADD CONSTRAINT "FK_0cfe8c83471aacc78bb6bf0d994" FOREIGN KEY ("threadId") REFERENCES "ai_user_threads"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "ai_user_threads" ADD CONSTRAINT "FK_90c549b96a3d29de5e38318e760" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "ai_user_files" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "file_ai_id" character varying(128) NOT NULL, "threadId" uuid, CONSTRAINT "REL_0cfe8c83471aacc78bb6bf0d99" UNIQUE ("threadId"), CONSTRAINT "PK_cad85eaa0e7888a70c543aea5ad" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `CREATE TABLE "ai_user_threads" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "thread_ai_id" character varying(128) NOT NULL, "userId" uuid, CONSTRAINT "PK_456c9992092ab18f4281ba54fd5" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "ai_user_files" ADD CONSTRAINT "FK_0cfe8c83471aacc78bb6bf0d994" FOREIGN KEY ("threadId") REFERENCES "ai_user_threads"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "ai_user_threads" ADD CONSTRAINT "FK_90c549b96a3d29de5e38318e760" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "ai_user_threads" DROP CONSTRAINT "FK_90c549b96a3d29de5e38318e760"`); - await queryRunner.query(`ALTER TABLE "ai_user_files" DROP CONSTRAINT "FK_0cfe8c83471aacc78bb6bf0d994"`); - await queryRunner.query(`DROP TABLE "ai_user_threads"`); - await queryRunner.query(`DROP TABLE "ai_user_files"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "ai_user_threads" DROP CONSTRAINT "FK_90c549b96a3d29de5e38318e760"`); + await queryRunner.query(`ALTER TABLE "ai_user_files" DROP CONSTRAINT "FK_0cfe8c83471aacc78bb6bf0d994"`); + await queryRunner.query(`DROP TABLE "ai_user_threads"`); + await queryRunner.query(`DROP TABLE "ai_user_files"`); + } } diff --git a/backend/src/migrations/1734690183411-AddCreatedAtPropertiesIntoAiEntitiesAddTitleToAiThreadEntity.ts b/backend/src/migrations/1734690183411-AddCreatedAtPropertiesIntoAiEntitiesAddTitleToAiThreadEntity.ts index 8adc12368..b0ee9ff24 100644 --- a/backend/src/migrations/1734690183411-AddCreatedAtPropertiesIntoAiEntitiesAddTitleToAiThreadEntity.ts +++ b/backend/src/migrations/1734690183411-AddCreatedAtPropertiesIntoAiEntitiesAddTitleToAiThreadEntity.ts @@ -1,17 +1,17 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddCreatedAtPropertiesIntoAiEntitiesAddTitleToAiThreadEntity1734690183411 implements MigrationInterface { - name = 'AddCreatedAtPropertiesIntoAiEntitiesAddTitleToAiThreadEntity1734690183411'; + name = 'AddCreatedAtPropertiesIntoAiEntitiesAddTitleToAiThreadEntity1734690183411'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "ai_user_files" ADD "createdAt" TIMESTAMP NOT NULL DEFAULT now()`); - await queryRunner.query(`ALTER TABLE "ai_user_threads" ADD "title" character varying(128)`); - await queryRunner.query(`ALTER TABLE "ai_user_threads" ADD "createdAt" TIMESTAMP NOT NULL DEFAULT now()`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "ai_user_files" ADD "createdAt" TIMESTAMP NOT NULL DEFAULT now()`); + await queryRunner.query(`ALTER TABLE "ai_user_threads" ADD "title" character varying(128)`); + await queryRunner.query(`ALTER TABLE "ai_user_threads" ADD "createdAt" TIMESTAMP NOT NULL DEFAULT now()`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "ai_user_threads" DROP COLUMN "createdAt"`); - await queryRunner.query(`ALTER TABLE "ai_user_threads" DROP COLUMN "title"`); - await queryRunner.query(`ALTER TABLE "ai_user_files" DROP COLUMN "createdAt"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "ai_user_threads" DROP COLUMN "createdAt"`); + await queryRunner.query(`ALTER TABLE "ai_user_threads" DROP COLUMN "title"`); + await queryRunner.query(`ALTER TABLE "ai_user_files" DROP COLUMN "createdAt"`); + } } diff --git a/backend/src/migrations/1736438355439-AddShowTestConnectionsPropertyInCompanyInfoEntity.ts b/backend/src/migrations/1736438355439-AddShowTestConnectionsPropertyInCompanyInfoEntity.ts index a87b9ab38..c6d41d462 100644 --- a/backend/src/migrations/1736438355439-AddShowTestConnectionsPropertyInCompanyInfoEntity.ts +++ b/backend/src/migrations/1736438355439-AddShowTestConnectionsPropertyInCompanyInfoEntity.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddShowTestConnectionsPropertyInCompanyInfoEntity1736438355439 implements MigrationInterface { - name = 'AddShowTestConnectionsPropertyInCompanyInfoEntity1736438355439'; + name = 'AddShowTestConnectionsPropertyInCompanyInfoEntity1736438355439'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "company_info" ADD "show_test_connections" boolean NOT NULL DEFAULT true`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "company_info" ADD "show_test_connections" boolean NOT NULL DEFAULT true`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "company_info" DROP COLUMN "show_test_connections"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "company_info" DROP COLUMN "show_test_connections"`); + } } diff --git a/backend/src/migrations/1739448612299-AddDefaultShowingTalbeIntoConnectionPropertiesEntity.ts b/backend/src/migrations/1739448612299-AddDefaultShowingTalbeIntoConnectionPropertiesEntity.ts index d0417631b..96d61b11e 100644 --- a/backend/src/migrations/1739448612299-AddDefaultShowingTalbeIntoConnectionPropertiesEntity.ts +++ b/backend/src/migrations/1739448612299-AddDefaultShowingTalbeIntoConnectionPropertiesEntity.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddDefaultShowingTalbeIntoConnectionPropertiesEntity1739448612299 implements MigrationInterface { - name = 'AddDefaultShowingTalbeIntoConnectionPropertiesEntity1739448612299'; + name = 'AddDefaultShowingTalbeIntoConnectionPropertiesEntity1739448612299'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "default_showing_table" character varying`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connectionProperties" ADD "default_showing_table" character varying`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "default_showing_table"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connectionProperties" DROP COLUMN "default_showing_table"`); + } } diff --git a/backend/src/migrations/1740129586002-AddDBAdminRoleToUserRoles.ts b/backend/src/migrations/1740129586002-AddDBAdminRoleToUserRoles.ts index 55755e46c..d4bbdc0b2 100644 --- a/backend/src/migrations/1740129586002-AddDBAdminRoleToUserRoles.ts +++ b/backend/src/migrations/1740129586002-AddDBAdminRoleToUserRoles.ts @@ -1,49 +1,49 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddDBAdminRoleToUserRoles1740129586002 implements MigrationInterface { - name = 'AddDBAdminRoleToUserRoles1740129586002'; + name = 'AddDBAdminRoleToUserRoles1740129586002'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `ALTER TYPE "public"."invitation_in_company_role_enum" RENAME TO "invitation_in_company_role_enum_old"`, - ); - await queryRunner.query( - `CREATE TYPE "public"."invitation_in_company_role_enum" AS ENUM('ADMIN', 'USER', 'DB_ADMIN')`, - ); - await queryRunner.query(`ALTER TABLE "invitation_in_company" ALTER COLUMN "role" DROP DEFAULT`); - await queryRunner.query( - `ALTER TABLE "invitation_in_company" ALTER COLUMN "role" TYPE "public"."invitation_in_company_role_enum" USING "role"::"text"::"public"."invitation_in_company_role_enum"`, - ); - await queryRunner.query(`ALTER TABLE "invitation_in_company" ALTER COLUMN "role" SET DEFAULT 'USER'`); - await queryRunner.query(`DROP TYPE "public"."invitation_in_company_role_enum_old"`); - await queryRunner.query(`ALTER TYPE "public"."user_role_enum" RENAME TO "user_role_enum_old"`); - await queryRunner.query(`CREATE TYPE "public"."user_role_enum" AS ENUM('ADMIN', 'USER', 'DB_ADMIN')`); - await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "role" DROP DEFAULT`); - await queryRunner.query( - `ALTER TABLE "user" ALTER COLUMN "role" TYPE "public"."user_role_enum" USING "role"::"text"::"public"."user_role_enum"`, - ); - await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "role" SET DEFAULT 'USER'`); - await queryRunner.query(`DROP TYPE "public"."user_role_enum_old"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TYPE "public"."invitation_in_company_role_enum" RENAME TO "invitation_in_company_role_enum_old"`, + ); + await queryRunner.query( + `CREATE TYPE "public"."invitation_in_company_role_enum" AS ENUM('ADMIN', 'USER', 'DB_ADMIN')`, + ); + await queryRunner.query(`ALTER TABLE "invitation_in_company" ALTER COLUMN "role" DROP DEFAULT`); + await queryRunner.query( + `ALTER TABLE "invitation_in_company" ALTER COLUMN "role" TYPE "public"."invitation_in_company_role_enum" USING "role"::"text"::"public"."invitation_in_company_role_enum"`, + ); + await queryRunner.query(`ALTER TABLE "invitation_in_company" ALTER COLUMN "role" SET DEFAULT 'USER'`); + await queryRunner.query(`DROP TYPE "public"."invitation_in_company_role_enum_old"`); + await queryRunner.query(`ALTER TYPE "public"."user_role_enum" RENAME TO "user_role_enum_old"`); + await queryRunner.query(`CREATE TYPE "public"."user_role_enum" AS ENUM('ADMIN', 'USER', 'DB_ADMIN')`); + await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "role" DROP DEFAULT`); + await queryRunner.query( + `ALTER TABLE "user" ALTER COLUMN "role" TYPE "public"."user_role_enum" USING "role"::"text"::"public"."user_role_enum"`, + ); + await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "role" SET DEFAULT 'USER'`); + await queryRunner.query(`DROP TYPE "public"."user_role_enum_old"`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TYPE "public"."user_role_enum_old" AS ENUM('ADMIN', 'USER')`); - await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "role" DROP DEFAULT`); - await queryRunner.query( - `ALTER TABLE "user" ALTER COLUMN "role" TYPE "public"."user_role_enum_old" USING "role"::"text"::"public"."user_role_enum_old"`, - ); - await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "role" SET DEFAULT 'USER'`); - await queryRunner.query(`DROP TYPE "public"."user_role_enum"`); - await queryRunner.query(`ALTER TYPE "public"."user_role_enum_old" RENAME TO "user_role_enum"`); - await queryRunner.query(`CREATE TYPE "public"."invitation_in_company_role_enum_old" AS ENUM('ADMIN', 'USER')`); - await queryRunner.query(`ALTER TABLE "invitation_in_company" ALTER COLUMN "role" DROP DEFAULT`); - await queryRunner.query( - `ALTER TABLE "invitation_in_company" ALTER COLUMN "role" TYPE "public"."invitation_in_company_role_enum_old" USING "role"::"text"::"public"."invitation_in_company_role_enum_old"`, - ); - await queryRunner.query(`ALTER TABLE "invitation_in_company" ALTER COLUMN "role" SET DEFAULT 'USER'`); - await queryRunner.query(`DROP TYPE "public"."invitation_in_company_role_enum"`); - await queryRunner.query( - `ALTER TYPE "public"."invitation_in_company_role_enum_old" RENAME TO "invitation_in_company_role_enum"`, - ); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TYPE "public"."user_role_enum_old" AS ENUM('ADMIN', 'USER')`); + await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "role" DROP DEFAULT`); + await queryRunner.query( + `ALTER TABLE "user" ALTER COLUMN "role" TYPE "public"."user_role_enum_old" USING "role"::"text"::"public"."user_role_enum_old"`, + ); + await queryRunner.query(`ALTER TABLE "user" ALTER COLUMN "role" SET DEFAULT 'USER'`); + await queryRunner.query(`DROP TYPE "public"."user_role_enum"`); + await queryRunner.query(`ALTER TYPE "public"."user_role_enum_old" RENAME TO "user_role_enum"`); + await queryRunner.query(`CREATE TYPE "public"."invitation_in_company_role_enum_old" AS ENUM('ADMIN', 'USER')`); + await queryRunner.query(`ALTER TABLE "invitation_in_company" ALTER COLUMN "role" DROP DEFAULT`); + await queryRunner.query( + `ALTER TABLE "invitation_in_company" ALTER COLUMN "role" TYPE "public"."invitation_in_company_role_enum_old" USING "role"::"text"::"public"."invitation_in_company_role_enum_old"`, + ); + await queryRunner.query(`ALTER TABLE "invitation_in_company" ALTER COLUMN "role" SET DEFAULT 'USER'`); + await queryRunner.query(`DROP TYPE "public"."invitation_in_company_role_enum"`); + await queryRunner.query( + `ALTER TYPE "public"."invitation_in_company_role_enum_old" RENAME TO "invitation_in_company_role_enum"`, + ); + } } diff --git a/backend/src/migrations/1742287157419-AddIsFrozenPropertyToConnectionEntity.ts b/backend/src/migrations/1742287157419-AddIsFrozenPropertyToConnectionEntity.ts index 960fe9879..21500c0df 100644 --- a/backend/src/migrations/1742287157419-AddIsFrozenPropertyToConnectionEntity.ts +++ b/backend/src/migrations/1742287157419-AddIsFrozenPropertyToConnectionEntity.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddIsFrozenPropertyToConnectionEntity1742287157419 implements MigrationInterface { - name = 'AddIsFrozenPropertyToConnectionEntity1742287157419'; + name = 'AddIsFrozenPropertyToConnectionEntity1742287157419'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" ADD "is_frozen" boolean NOT NULL DEFAULT false`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" ADD "is_frozen" boolean NOT NULL DEFAULT false`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "is_frozen"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "is_frozen"`); + } } diff --git a/backend/src/migrations/1743499096176-AddCompanyLogoEntity.ts b/backend/src/migrations/1743499096176-AddCompanyLogoEntity.ts index 0bf8aa2a6..994206ee2 100644 --- a/backend/src/migrations/1743499096176-AddCompanyLogoEntity.ts +++ b/backend/src/migrations/1743499096176-AddCompanyLogoEntity.ts @@ -1,21 +1,21 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddCompanyLogoEntity1743499096176 implements MigrationInterface { - name = 'AddCompanyLogoEntity1743499096176'; + name = 'AddCompanyLogoEntity1743499096176'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TABLE "company_logo" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "logo" bytea, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "companyId" uuid, CONSTRAINT "REL_a92f3f071257d7fdf90eeddf0b" UNIQUE ("companyId"), CONSTRAINT "PK_23de0dcd3f7763e16c418cd8a9c" PRIMARY KEY ("id"))`, - ); - await queryRunner.query(`ALTER TABLE "company_info" ADD "createdAt" TIMESTAMP NOT NULL DEFAULT now()`); - await queryRunner.query( - `ALTER TABLE "company_logo" ADD CONSTRAINT "FK_a92f3f071257d7fdf90eeddf0b6" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "company_logo" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "logo" bytea, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "companyId" uuid, CONSTRAINT "REL_a92f3f071257d7fdf90eeddf0b" UNIQUE ("companyId"), CONSTRAINT "PK_23de0dcd3f7763e16c418cd8a9c" PRIMARY KEY ("id"))`, + ); + await queryRunner.query(`ALTER TABLE "company_info" ADD "createdAt" TIMESTAMP NOT NULL DEFAULT now()`); + await queryRunner.query( + `ALTER TABLE "company_logo" ADD CONSTRAINT "FK_a92f3f071257d7fdf90eeddf0b6" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "company_logo" DROP CONSTRAINT "FK_a92f3f071257d7fdf90eeddf0b6"`); - await queryRunner.query(`ALTER TABLE "company_info" DROP COLUMN "createdAt"`); - await queryRunner.query(`DROP TABLE "company_logo"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "company_logo" DROP CONSTRAINT "FK_a92f3f071257d7fdf90eeddf0b6"`); + await queryRunner.query(`ALTER TABLE "company_info" DROP COLUMN "createdAt"`); + await queryRunner.query(`DROP TABLE "company_logo"`); + } } diff --git a/backend/src/migrations/1743598451177-AddMimeTypeToCompanyLogoEntityRenameLogoProperty.ts b/backend/src/migrations/1743598451177-AddMimeTypeToCompanyLogoEntityRenameLogoProperty.ts index 623cb8e51..2208c7254 100644 --- a/backend/src/migrations/1743598451177-AddMimeTypeToCompanyLogoEntityRenameLogoProperty.ts +++ b/backend/src/migrations/1743598451177-AddMimeTypeToCompanyLogoEntityRenameLogoProperty.ts @@ -1,17 +1,17 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddMimeTypeToCompanyLogoEntityRenameLogoProperty1743598451177 implements MigrationInterface { - name = 'AddMimeTypeToCompanyLogoEntityRenameLogoProperty1743598451177'; + name = 'AddMimeTypeToCompanyLogoEntityRenameLogoProperty1743598451177'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "company_logo" RENAME COLUMN "logo" TO "image"`); - await queryRunner.query( - `ALTER TABLE "company_logo" ADD "mimeType" character varying(24) NOT NULL DEFAULT 'image/png'`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "company_logo" RENAME COLUMN "logo" TO "image"`); + await queryRunner.query( + `ALTER TABLE "company_logo" ADD "mimeType" character varying(24) NOT NULL DEFAULT 'image/png'`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "company_logo" DROP COLUMN "mimeType"`); - await queryRunner.query(`ALTER TABLE "company_logo" RENAME COLUMN "image" TO "logo"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "company_logo" DROP COLUMN "mimeType"`); + await queryRunner.query(`ALTER TABLE "company_logo" RENAME COLUMN "image" TO "logo"`); + } } diff --git a/backend/src/migrations/1744184153482-AddCompanyFaviconEntity.ts b/backend/src/migrations/1744184153482-AddCompanyFaviconEntity.ts index 182ea6d80..e136d6632 100644 --- a/backend/src/migrations/1744184153482-AddCompanyFaviconEntity.ts +++ b/backend/src/migrations/1744184153482-AddCompanyFaviconEntity.ts @@ -1,19 +1,19 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddCompanyFaviconEntity1744184153482 implements MigrationInterface { - name = 'AddCompanyFaviconEntity1744184153482'; + name = 'AddCompanyFaviconEntity1744184153482'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TABLE "company_favicon" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "image" bytea, "mimeType" character varying(24) NOT NULL DEFAULT 'image/png', "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "companyId" uuid, CONSTRAINT "REL_c7d59fe50a759a6d9c6003d8d0" UNIQUE ("companyId"), CONSTRAINT "PK_c8df420c440781f6a98258cd82e" PRIMARY KEY ("id"))`, - ); - await queryRunner.query( - `ALTER TABLE "company_favicon" ADD CONSTRAINT "FK_c7d59fe50a759a6d9c6003d8d0a" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "company_favicon" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "image" bytea, "mimeType" character varying(24) NOT NULL DEFAULT 'image/png', "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "companyId" uuid, CONSTRAINT "REL_c7d59fe50a759a6d9c6003d8d0" UNIQUE ("companyId"), CONSTRAINT "PK_c8df420c440781f6a98258cd82e" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "company_favicon" ADD CONSTRAINT "FK_c7d59fe50a759a6d9c6003d8d0a" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "company_favicon" DROP CONSTRAINT "FK_c7d59fe50a759a6d9c6003d8d0a"`); - await queryRunner.query(`DROP TABLE "company_favicon"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "company_favicon" DROP CONSTRAINT "FK_c7d59fe50a759a6d9c6003d8d0a"`); + await queryRunner.query(`DROP TABLE "company_favicon"`); + } } diff --git a/backend/src/migrations/1744190012692-AddTabTitleEntity.ts b/backend/src/migrations/1744190012692-AddTabTitleEntity.ts index 3ba5aa886..40657b72e 100644 --- a/backend/src/migrations/1744190012692-AddTabTitleEntity.ts +++ b/backend/src/migrations/1744190012692-AddTabTitleEntity.ts @@ -1,19 +1,19 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddTabTitleEntity1744190012692 implements MigrationInterface { - name = 'AddTabTitleEntity1744190012692'; + name = 'AddTabTitleEntity1744190012692'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TABLE "company_tab_title" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "text" character varying(255), "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "companyId" uuid, CONSTRAINT "REL_f17247dfca2ba090456a1f8040" UNIQUE ("companyId"), CONSTRAINT "PK_bc41f9fc386503ed484c6c7ca18" PRIMARY KEY ("id"))`, - ); - await queryRunner.query( - `ALTER TABLE "company_tab_title" ADD CONSTRAINT "FK_f17247dfca2ba090456a1f80401" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "company_tab_title" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "text" character varying(255), "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "companyId" uuid, CONSTRAINT "REL_f17247dfca2ba090456a1f8040" UNIQUE ("companyId"), CONSTRAINT "PK_bc41f9fc386503ed484c6c7ca18" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "company_tab_title" ADD CONSTRAINT "FK_f17247dfca2ba090456a1f80401" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "company_tab_title" DROP CONSTRAINT "FK_f17247dfca2ba090456a1f80401"`); - await queryRunner.query(`DROP TABLE "company_tab_title"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "company_tab_title" DROP CONSTRAINT "FK_f17247dfca2ba090456a1f80401"`); + await queryRunner.query(`DROP TABLE "company_tab_title"`); + } } diff --git a/backend/src/migrations/1744468758029-AddTableFiltersEntity.ts b/backend/src/migrations/1744468758029-AddTableFiltersEntity.ts index 6d9b5e86d..089d382f4 100644 --- a/backend/src/migrations/1744468758029-AddTableFiltersEntity.ts +++ b/backend/src/migrations/1744468758029-AddTableFiltersEntity.ts @@ -1,19 +1,19 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddTableFiltersEntity1744468758029 implements MigrationInterface { - name = 'AddTableFiltersEntity1744468758029'; + name = 'AddTableFiltersEntity1744468758029'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TABLE "table_filters" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "filters" jsonb, "table_name" character varying, "connectionId" character varying NOT NULL, CONSTRAINT "UQ_86da06a7ee22ca03ec25bf681de" UNIQUE ("connectionId", "table_name"), CONSTRAINT "PK_3e08a731402b35d32fe6f062c13" PRIMARY KEY ("id"))`, - ); - await queryRunner.query( - `ALTER TABLE "table_filters" ADD CONSTRAINT "FK_e4b16eddf2b9b90d5776b9652fc" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "table_filters" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "filters" jsonb, "table_name" character varying, "connectionId" character varying NOT NULL, CONSTRAINT "UQ_86da06a7ee22ca03ec25bf681de" UNIQUE ("connectionId", "table_name"), CONSTRAINT "PK_3e08a731402b35d32fe6f062c13" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "table_filters" ADD CONSTRAINT "FK_e4b16eddf2b9b90d5776b9652fc" FOREIGN KEY ("connectionId") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_filters" DROP CONSTRAINT "FK_e4b16eddf2b9b90d5776b9652fc"`); - await queryRunner.query(`DROP TABLE "table_filters"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_filters" DROP CONSTRAINT "FK_e4b16eddf2b9b90d5776b9652fc"`); + await queryRunner.query(`DROP TABLE "table_filters"`); + } } diff --git a/backend/src/migrations/1744639769722-ReworkTableFiltersEntity.ts b/backend/src/migrations/1744639769722-ReworkTableFiltersEntity.ts index 72929dc97..4481583f0 100644 --- a/backend/src/migrations/1744639769722-ReworkTableFiltersEntity.ts +++ b/backend/src/migrations/1744639769722-ReworkTableFiltersEntity.ts @@ -1,31 +1,31 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class ReworkTableFiltersEntity1744639769722 implements MigrationInterface { - name = 'ReworkTableFiltersEntity1744639769722'; + name = 'ReworkTableFiltersEntity1744639769722'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_filters" DROP CONSTRAINT "UQ_86da06a7ee22ca03ec25bf681de"`); - await queryRunner.query(`ALTER TABLE "table_filters" ADD "name" character varying(255)`); - await queryRunner.query(`ALTER TABLE "table_filters" ADD "dynamic_filter_column_name" character varying(255)`); - await queryRunner.query( - `CREATE TYPE "public"."table_filters_dynamic_filter_comparator_enum" AS ENUM('startswith', 'endswith', 'gt', 'lt', 'lte', 'gte', 'contains', 'icontains', 'eq', 'empty')`, - ); - await queryRunner.query( - `ALTER TABLE "table_filters" ADD "dynamic_filter_comparator" "public"."table_filters_dynamic_filter_comparator_enum"`, - ); - await queryRunner.query(`ALTER TABLE "table_filters" ADD "createdAt" TIMESTAMP NOT NULL DEFAULT now()`); - await queryRunner.query(`ALTER TABLE "table_filters" ADD "updatedAt" TIMESTAMP`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_filters" DROP CONSTRAINT "UQ_86da06a7ee22ca03ec25bf681de"`); + await queryRunner.query(`ALTER TABLE "table_filters" ADD "name" character varying(255)`); + await queryRunner.query(`ALTER TABLE "table_filters" ADD "dynamic_filter_column_name" character varying(255)`); + await queryRunner.query( + `CREATE TYPE "public"."table_filters_dynamic_filter_comparator_enum" AS ENUM('startswith', 'endswith', 'gt', 'lt', 'lte', 'gte', 'contains', 'icontains', 'eq', 'empty')`, + ); + await queryRunner.query( + `ALTER TABLE "table_filters" ADD "dynamic_filter_comparator" "public"."table_filters_dynamic_filter_comparator_enum"`, + ); + await queryRunner.query(`ALTER TABLE "table_filters" ADD "createdAt" TIMESTAMP NOT NULL DEFAULT now()`); + await queryRunner.query(`ALTER TABLE "table_filters" ADD "updatedAt" TIMESTAMP`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_filters" DROP COLUMN "updatedAt"`); - await queryRunner.query(`ALTER TABLE "table_filters" DROP COLUMN "createdAt"`); - await queryRunner.query(`ALTER TABLE "table_filters" DROP COLUMN "dynamic_filter_comparator"`); - await queryRunner.query(`DROP TYPE "public"."table_filters_dynamic_filter_comparator_enum"`); - await queryRunner.query(`ALTER TABLE "table_filters" DROP COLUMN "dynamic_filter_column_name"`); - await queryRunner.query(`ALTER TABLE "table_filters" DROP COLUMN "name"`); - await queryRunner.query( - `ALTER TABLE "table_filters" ADD CONSTRAINT "UQ_86da06a7ee22ca03ec25bf681de" UNIQUE ("table_name", "connectionId")`, - ); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_filters" DROP COLUMN "updatedAt"`); + await queryRunner.query(`ALTER TABLE "table_filters" DROP COLUMN "createdAt"`); + await queryRunner.query(`ALTER TABLE "table_filters" DROP COLUMN "dynamic_filter_comparator"`); + await queryRunner.query(`DROP TYPE "public"."table_filters_dynamic_filter_comparator_enum"`); + await queryRunner.query(`ALTER TABLE "table_filters" DROP COLUMN "dynamic_filter_column_name"`); + await queryRunner.query(`ALTER TABLE "table_filters" DROP COLUMN "name"`); + await queryRunner.query( + `ALTER TABLE "table_filters" ADD CONSTRAINT "UQ_86da06a7ee22ca03ec25bf681de" UNIQUE ("table_name", "connectionId")`, + ); + } } diff --git a/backend/src/migrations/1747235569575-AddIsDemoAccountToUserEntity.ts b/backend/src/migrations/1747235569575-AddIsDemoAccountToUserEntity.ts index c9e347e7f..0ddd4cd24 100644 --- a/backend/src/migrations/1747235569575-AddIsDemoAccountToUserEntity.ts +++ b/backend/src/migrations/1747235569575-AddIsDemoAccountToUserEntity.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddIsDemoAccountToUserEntity1747235569575 implements MigrationInterface { - name = 'AddIsDemoAccountToUserEntity1747235569575'; + name = 'AddIsDemoAccountToUserEntity1747235569575'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" ADD "isDemoAccount" boolean NOT NULL DEFAULT false`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" ADD "isDemoAccount" boolean NOT NULL DEFAULT false`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "isDemoAccount"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "isDemoAccount"`); + } } diff --git a/backend/src/migrations/1748002305012-AddSamlPropertiesToUserEntity.ts b/backend/src/migrations/1748002305012-AddSamlPropertiesToUserEntity.ts index ab058662d..53481d310 100644 --- a/backend/src/migrations/1748002305012-AddSamlPropertiesToUserEntity.ts +++ b/backend/src/migrations/1748002305012-AddSamlPropertiesToUserEntity.ts @@ -1,33 +1,33 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddSamlPropertiesToUserEntity1748002305012 implements MigrationInterface { - name = 'AddSamlPropertiesToUserEntity1748002305012'; + name = 'AddSamlPropertiesToUserEntity1748002305012'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user" ADD "samlNameId" character varying`); - await queryRunner.query( - `ALTER TYPE "public"."user_externalregistrationprovider_enum" RENAME TO "user_externalregistrationprovider_enum_old"`, - ); - await queryRunner.query( - `CREATE TYPE "public"."user_externalregistrationprovider_enum" AS ENUM('GOOGLE', 'GITHUB', 'SAML')`, - ); - await queryRunner.query( - `ALTER TABLE "user" ALTER COLUMN "externalRegistrationProvider" TYPE "public"."user_externalregistrationprovider_enum" USING "externalRegistrationProvider"::"text"::"public"."user_externalregistrationprovider_enum"`, - ); - await queryRunner.query(`DROP TYPE "public"."user_externalregistrationprovider_enum_old"`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user" ADD "samlNameId" character varying`); + await queryRunner.query( + `ALTER TYPE "public"."user_externalregistrationprovider_enum" RENAME TO "user_externalregistrationprovider_enum_old"`, + ); + await queryRunner.query( + `CREATE TYPE "public"."user_externalregistrationprovider_enum" AS ENUM('GOOGLE', 'GITHUB', 'SAML')`, + ); + await queryRunner.query( + `ALTER TABLE "user" ALTER COLUMN "externalRegistrationProvider" TYPE "public"."user_externalregistrationprovider_enum" USING "externalRegistrationProvider"::"text"::"public"."user_externalregistrationprovider_enum"`, + ); + await queryRunner.query(`DROP TYPE "public"."user_externalregistrationprovider_enum_old"`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TYPE "public"."user_externalregistrationprovider_enum_old" AS ENUM('GOOGLE', 'GITHUB')`, - ); - await queryRunner.query( - `ALTER TABLE "user" ALTER COLUMN "externalRegistrationProvider" TYPE "public"."user_externalregistrationprovider_enum_old" USING "externalRegistrationProvider"::"text"::"public"."user_externalregistrationprovider_enum_old"`, - ); - await queryRunner.query(`DROP TYPE "public"."user_externalregistrationprovider_enum"`); - await queryRunner.query( - `ALTER TYPE "public"."user_externalregistrationprovider_enum_old" RENAME TO "user_externalregistrationprovider_enum"`, - ); - await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "samlNameId"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TYPE "public"."user_externalregistrationprovider_enum_old" AS ENUM('GOOGLE', 'GITHUB')`, + ); + await queryRunner.query( + `ALTER TABLE "user" ALTER COLUMN "externalRegistrationProvider" TYPE "public"."user_externalregistrationprovider_enum_old" USING "externalRegistrationProvider"::"text"::"public"."user_externalregistrationprovider_enum_old"`, + ); + await queryRunner.query(`DROP TYPE "public"."user_externalregistrationprovider_enum"`); + await queryRunner.query( + `ALTER TYPE "public"."user_externalregistrationprovider_enum_old" RENAME TO "user_externalregistrationprovider_enum"`, + ); + await queryRunner.query(`ALTER TABLE "user" DROP COLUMN "samlNameId"`); + } } diff --git a/backend/src/migrations/1750931986538-AddDataCenterInConnectionEntity.ts b/backend/src/migrations/1750931986538-AddDataCenterInConnectionEntity.ts index e07d372a2..ca25931ff 100644 --- a/backend/src/migrations/1750931986538-AddDataCenterInConnectionEntity.ts +++ b/backend/src/migrations/1750931986538-AddDataCenterInConnectionEntity.ts @@ -1,13 +1,13 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddDataCenterInConnectionEntity1750931986538 implements MigrationInterface { - name = 'AddDataCenterInConnectionEntity1750931986538'; + name = 'AddDataCenterInConnectionEntity1750931986538'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" ADD "dataCenter" character varying`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" ADD "dataCenter" character varying`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "dataCenter"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connection" DROP COLUMN "dataCenter"`); + } } diff --git a/backend/src/migrations/1755522332243-AddAiResponsesToUserEntity.ts b/backend/src/migrations/1755522332243-AddAiResponsesToUserEntity.ts index 750bc7c51..7e8c4a05f 100644 --- a/backend/src/migrations/1755522332243-AddAiResponsesToUserEntity.ts +++ b/backend/src/migrations/1755522332243-AddAiResponsesToUserEntity.ts @@ -1,19 +1,19 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddAiResponsesToUserEntity1755522332243 implements MigrationInterface { - name = 'AddAiResponsesToUserEntity1755522332243'; + name = 'AddAiResponsesToUserEntity1755522332243'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TABLE "ai_responses_to_user" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "ai_response_id" character varying(128), "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP, "user_id" uuid NOT NULL, CONSTRAINT "PK_15fbf891f35af2e741eb7a6a4c1" PRIMARY KEY ("id"))`, - ); - await queryRunner.query( - `ALTER TABLE "ai_responses_to_user" ADD CONSTRAINT "FK_ccf6477f9644155217bb7698606" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "ai_responses_to_user" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "ai_response_id" character varying(128), "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP, "user_id" uuid NOT NULL, CONSTRAINT "PK_15fbf891f35af2e741eb7a6a4c1" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "ai_responses_to_user" ADD CONSTRAINT "FK_ccf6477f9644155217bb7698606" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "ai_responses_to_user" DROP CONSTRAINT "FK_ccf6477f9644155217bb7698606"`); - await queryRunner.query(`DROP TABLE "ai_responses_to_user"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "ai_responses_to_user" DROP CONSTRAINT "FK_ccf6477f9644155217bb7698606"`); + await queryRunner.query(`DROP TABLE "ai_responses_to_user"`); + } } diff --git a/backend/src/migrations/1758113168067-AddTableCategoriesEntity.ts b/backend/src/migrations/1758113168067-AddTableCategoriesEntity.ts index 83b0f9e4e..bb0339675 100644 --- a/backend/src/migrations/1758113168067-AddTableCategoriesEntity.ts +++ b/backend/src/migrations/1758113168067-AddTableCategoriesEntity.ts @@ -1,19 +1,19 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddTableCategoriesEntity1758113168067 implements MigrationInterface { - name = 'AddTableCategoriesEntity1758113168067'; + name = 'AddTableCategoriesEntity1758113168067'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query( - `CREATE TABLE "table_categories" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "category_name" character varying(255) NOT NULL, "tables" character varying array, "connection_properties_id" uuid NOT NULL, CONSTRAINT "PK_25ba8fc29388a10d70db9e0d3d0" PRIMARY KEY ("id"))`, - ); - await queryRunner.query( - `ALTER TABLE "table_categories" ADD CONSTRAINT "FK_05bd0df6a5f40f4a992b9821e98" FOREIGN KEY ("connection_properties_id") REFERENCES "connectionProperties"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TABLE "table_categories" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "category_name" character varying(255) NOT NULL, "tables" character varying array, "connection_properties_id" uuid NOT NULL, CONSTRAINT "PK_25ba8fc29388a10d70db9e0d3d0" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "table_categories" ADD CONSTRAINT "FK_05bd0df6a5f40f4a992b9821e98" FOREIGN KEY ("connection_properties_id") REFERENCES "connectionProperties"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_categories" DROP CONSTRAINT "FK_05bd0df6a5f40f4a992b9821e98"`); - await queryRunner.query(`DROP TABLE "table_categories"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_categories" DROP CONSTRAINT "FK_05bd0df6a5f40f4a992b9821e98"`); + await queryRunner.query(`DROP TABLE "table_categories"`); + } } diff --git a/backend/src/migrations/1761305606579-AddCategoryColorPropertyAndCategoryIdToTableCategoriesEntity.ts b/backend/src/migrations/1761305606579-AddCategoryColorPropertyAndCategoryIdToTableCategoriesEntity.ts index d84ca94fa..1668a583e 100644 --- a/backend/src/migrations/1761305606579-AddCategoryColorPropertyAndCategoryIdToTableCategoriesEntity.ts +++ b/backend/src/migrations/1761305606579-AddCategoryColorPropertyAndCategoryIdToTableCategoriesEntity.ts @@ -1,15 +1,15 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddCategoryColorPropertyAndCategoryIdToTableCategoriesEntity1761305606579 implements MigrationInterface { - name = 'AddCategoryColorPropertyAndCategoryIdToTableCategoriesEntity1761305606579'; + name = 'AddCategoryColorPropertyAndCategoryIdToTableCategoriesEntity1761305606579'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_categories" ADD "category_id" character varying(255)`); - await queryRunner.query(`ALTER TABLE "table_categories" ADD "category_color" character varying(255)`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_categories" ADD "category_id" character varying(255)`); + await queryRunner.query(`ALTER TABLE "table_categories" ADD "category_color" character varying(255)`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "table_categories" DROP COLUMN "category_color"`); - await queryRunner.query(`ALTER TABLE "table_categories" DROP COLUMN "category_id"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "table_categories" DROP COLUMN "category_color"`); + await queryRunner.query(`ALTER TABLE "table_categories" DROP COLUMN "category_id"`); + } } diff --git a/backend/src/migrations/1762258082256-ChangeDefultColorValuesInConnectionProperties.ts b/backend/src/migrations/1762258082256-ChangeDefultColorValuesInConnectionProperties.ts index 53697f8fc..4e630d423 100644 --- a/backend/src/migrations/1762258082256-ChangeDefultColorValuesInConnectionProperties.ts +++ b/backend/src/migrations/1762258082256-ChangeDefultColorValuesInConnectionProperties.ts @@ -1,21 +1,21 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class ChangeDefultColorValuesInConnectionProperties1762258082256 implements MigrationInterface { - name = 'ChangeDefultColorValuesInConnectionProperties1762258082256'; + name = 'ChangeDefultColorValuesInConnectionProperties1762258082256'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connectionProperties" ALTER COLUMN "primary_color" SET DEFAULT ''`); - await queryRunner.query(`UPDATE "connectionProperties" SET "primary_color" = '' WHERE "primary_color" IS NULL`); - await queryRunner.query(`ALTER TABLE "connectionProperties" ALTER COLUMN "primary_color" SET NOT NULL`); - await queryRunner.query(`ALTER TABLE "connectionProperties" ALTER COLUMN "secondary_color" SET DEFAULT ''`); - await queryRunner.query(`UPDATE "connectionProperties" SET "secondary_color" = '' WHERE "secondary_color" IS NULL`); - await queryRunner.query(`ALTER TABLE "connectionProperties" ALTER COLUMN "secondary_color" SET NOT NULL`); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connectionProperties" ALTER COLUMN "primary_color" SET DEFAULT ''`); + await queryRunner.query(`UPDATE "connectionProperties" SET "primary_color" = '' WHERE "primary_color" IS NULL`); + await queryRunner.query(`ALTER TABLE "connectionProperties" ALTER COLUMN "primary_color" SET NOT NULL`); + await queryRunner.query(`ALTER TABLE "connectionProperties" ALTER COLUMN "secondary_color" SET DEFAULT ''`); + await queryRunner.query(`UPDATE "connectionProperties" SET "secondary_color" = '' WHERE "secondary_color" IS NULL`); + await queryRunner.query(`ALTER TABLE "connectionProperties" ALTER COLUMN "secondary_color" SET NOT NULL`); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "connectionProperties" ALTER COLUMN "secondary_color" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "connectionProperties" ALTER COLUMN "secondary_color" DROP NOT NULL`); - await queryRunner.query(`ALTER TABLE "connectionProperties" ALTER COLUMN "primary_color" DROP DEFAULT`); - await queryRunner.query(`ALTER TABLE "connectionProperties" ALTER COLUMN "primary_color" DROP NOT NULL`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "connectionProperties" ALTER COLUMN "secondary_color" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "connectionProperties" ALTER COLUMN "secondary_color" DROP NOT NULL`); + await queryRunner.query(`ALTER TABLE "connectionProperties" ALTER COLUMN "primary_color" DROP DEFAULT`); + await queryRunner.query(`ALTER TABLE "connectionProperties" ALTER COLUMN "primary_color" DROP NOT NULL`); + } } diff --git a/backend/src/migrations/1762528788423-AddPersonalTableSettingsEntityRemovePropertiesFromTableSettingsEntity.ts b/backend/src/migrations/1762528788423-AddPersonalTableSettingsEntityRemovePropertiesFromTableSettingsEntity.ts index b1cbab031..2cf5aab68 100644 --- a/backend/src/migrations/1762528788423-AddPersonalTableSettingsEntityRemovePropertiesFromTableSettingsEntity.ts +++ b/backend/src/migrations/1762528788423-AddPersonalTableSettingsEntityRemovePropertiesFromTableSettingsEntity.ts @@ -1,41 +1,41 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddPersonalTableSettingsEntityRemovePropertiesFromTableSettingsEntity1762528788423 - implements MigrationInterface + implements MigrationInterface { - name = 'AddPersonalTableSettingsEntityRemovePropertiesFromTableSettingsEntity1762528788423'; + name = 'AddPersonalTableSettingsEntityRemovePropertiesFromTableSettingsEntity1762528788423'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TYPE "public"."personal_table_settings_ordering_enum" AS ENUM('ASC', 'DESC')`); - await queryRunner.query( - `CREATE TABLE "personal_table_settings" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "table_name" character varying, "ordering" "public"."personal_table_settings_ordering_enum" NOT NULL DEFAULT 'ASC', "ordering_field" character varying, "list_per_page" integer, "list_fields" character varying array NOT NULL DEFAULT '{}', "columns_view" character varying array NOT NULL DEFAULT '{}', "original_names" boolean NOT NULL DEFAULT false, "connection_id" character varying NOT NULL, "user_id" uuid NOT NULL, CONSTRAINT "PK_9a4d9b32ced3b0514314a5dc49d" PRIMARY KEY ("id"))`, - ); - await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "list_per_page"`); - await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "ordering"`); - await queryRunner.query(`DROP TYPE "public"."tableSettings_ordering_enum"`); - await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "list_fields"`); - await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "ordering_field"`); - await queryRunner.query( - `ALTER TABLE "personal_table_settings" ADD CONSTRAINT "FK_8a64b754616c7c8e5e0e6bc4343" FOREIGN KEY ("connection_id") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - await queryRunner.query( - `ALTER TABLE "personal_table_settings" ADD CONSTRAINT "FK_d9c9dcfd4a151818428a9cf8025" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TYPE "public"."personal_table_settings_ordering_enum" AS ENUM('ASC', 'DESC')`); + await queryRunner.query( + `CREATE TABLE "personal_table_settings" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "table_name" character varying, "ordering" "public"."personal_table_settings_ordering_enum" NOT NULL DEFAULT 'ASC', "ordering_field" character varying, "list_per_page" integer, "list_fields" character varying array NOT NULL DEFAULT '{}', "columns_view" character varying array NOT NULL DEFAULT '{}', "original_names" boolean NOT NULL DEFAULT false, "connection_id" character varying NOT NULL, "user_id" uuid NOT NULL, CONSTRAINT "PK_9a4d9b32ced3b0514314a5dc49d" PRIMARY KEY ("id"))`, + ); + await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "list_per_page"`); + await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "ordering"`); + await queryRunner.query(`DROP TYPE "public"."tableSettings_ordering_enum"`); + await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "list_fields"`); + await queryRunner.query(`ALTER TABLE "tableSettings" DROP COLUMN "ordering_field"`); + await queryRunner.query( + `ALTER TABLE "personal_table_settings" ADD CONSTRAINT "FK_8a64b754616c7c8e5e0e6bc4343" FOREIGN KEY ("connection_id") REFERENCES "connection"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "personal_table_settings" ADD CONSTRAINT "FK_d9c9dcfd4a151818428a9cf8025" FOREIGN KEY ("user_id") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "personal_table_settings" DROP CONSTRAINT "FK_d9c9dcfd4a151818428a9cf8025"`); - await queryRunner.query(`ALTER TABLE "personal_table_settings" DROP CONSTRAINT "FK_8a64b754616c7c8e5e0e6bc4343"`); - await queryRunner.query(`ALTER TABLE "tableSettings" ADD "ordering_field" character varying`); - await queryRunner.query( - `ALTER TABLE "tableSettings" ADD "list_fields" character varying array NOT NULL DEFAULT '{}'`, - ); - await queryRunner.query(`CREATE TYPE "public"."tableSettings_ordering_enum" AS ENUM('ASC', 'DESC')`); - await queryRunner.query( - `ALTER TABLE "tableSettings" ADD "ordering" "public"."tableSettings_ordering_enum" NOT NULL DEFAULT 'ASC'`, - ); - await queryRunner.query(`ALTER TABLE "tableSettings" ADD "list_per_page" integer`); - await queryRunner.query(`DROP TABLE "personal_table_settings"`); - await queryRunner.query(`DROP TYPE "public"."personal_table_settings_ordering_enum"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "personal_table_settings" DROP CONSTRAINT "FK_d9c9dcfd4a151818428a9cf8025"`); + await queryRunner.query(`ALTER TABLE "personal_table_settings" DROP CONSTRAINT "FK_8a64b754616c7c8e5e0e6bc4343"`); + await queryRunner.query(`ALTER TABLE "tableSettings" ADD "ordering_field" character varying`); + await queryRunner.query( + `ALTER TABLE "tableSettings" ADD "list_fields" character varying array NOT NULL DEFAULT '{}'`, + ); + await queryRunner.query(`CREATE TYPE "public"."tableSettings_ordering_enum" AS ENUM('ASC', 'DESC')`); + await queryRunner.query( + `ALTER TABLE "tableSettings" ADD "ordering" "public"."tableSettings_ordering_enum" NOT NULL DEFAULT 'ASC'`, + ); + await queryRunner.query(`ALTER TABLE "tableSettings" ADD "list_per_page" integer`); + await queryRunner.query(`DROP TABLE "personal_table_settings"`); + await queryRunner.query(`DROP TYPE "public"."personal_table_settings_ordering_enum"`); + } } diff --git a/backend/src/migrations/1763724061000-CreateUserSecretEntity.ts b/backend/src/migrations/1763724061000-CreateUserSecretEntity.ts index 805608c81..03ca4fc00 100644 --- a/backend/src/migrations/1763724061000-CreateUserSecretEntity.ts +++ b/backend/src/migrations/1763724061000-CreateUserSecretEntity.ts @@ -1,10 +1,10 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class CreateUserSecretEntity1763724061000 implements MigrationInterface { - name = 'CreateUserSecretEntity1763724061000' + name = 'CreateUserSecretEntity1763724061000'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "user_secrets" ( + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TABLE "user_secrets" ( "id" uuid NOT NULL DEFAULT uuid_generate_v4(), "companyId" uuid NOT NULL, "slug" character varying(255) NOT NULL, @@ -18,21 +18,24 @@ export class CreateUserSecretEntity1763724061000 implements MigrationInterface { CONSTRAINT "PK_user_secrets" PRIMARY KEY ("id") )`); - await queryRunner.query(`CREATE INDEX "IDX_user_secrets_companyId" ON "user_secrets" ("companyId")`); - await queryRunner.query(`CREATE INDEX "IDX_user_secrets_createdAt" ON "user_secrets" ("createdAt")`); - await queryRunner.query(`CREATE INDEX "IDX_user_secrets_expiresAt" ON "user_secrets" ("expiresAt")`); - await queryRunner.query(`CREATE UNIQUE INDEX "IDX_user_secrets_company_slug" ON "user_secrets" ("companyId", "slug")`); + await queryRunner.query(`CREATE INDEX "IDX_user_secrets_companyId" ON "user_secrets" ("companyId")`); + await queryRunner.query(`CREATE INDEX "IDX_user_secrets_createdAt" ON "user_secrets" ("createdAt")`); + await queryRunner.query(`CREATE INDEX "IDX_user_secrets_expiresAt" ON "user_secrets" ("expiresAt")`); + await queryRunner.query( + `CREATE UNIQUE INDEX "IDX_user_secrets_company_slug" ON "user_secrets" ("companyId", "slug")`, + ); - await queryRunner.query(`ALTER TABLE "user_secrets" ADD CONSTRAINT "FK_user_secrets_companyId" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "user_secrets" DROP CONSTRAINT "FK_user_secrets_companyId"`); - await queryRunner.query(`DROP INDEX "IDX_user_secrets_company_slug"`); - await queryRunner.query(`DROP INDEX "IDX_user_secrets_expiresAt"`); - await queryRunner.query(`DROP INDEX "IDX_user_secrets_createdAt"`); - await queryRunner.query(`DROP INDEX "IDX_user_secrets_companyId"`); - await queryRunner.query(`DROP TABLE "user_secrets"`); - } + await queryRunner.query( + `ALTER TABLE "user_secrets" ADD CONSTRAINT "FK_user_secrets_companyId" FOREIGN KEY ("companyId") REFERENCES "company_info"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "user_secrets" DROP CONSTRAINT "FK_user_secrets_companyId"`); + await queryRunner.query(`DROP INDEX "IDX_user_secrets_company_slug"`); + await queryRunner.query(`DROP INDEX "IDX_user_secrets_expiresAt"`); + await queryRunner.query(`DROP INDEX "IDX_user_secrets_createdAt"`); + await queryRunner.query(`DROP INDEX "IDX_user_secrets_companyId"`); + await queryRunner.query(`DROP TABLE "user_secrets"`); + } } diff --git a/backend/src/migrations/1763724062000-CreateSecretAccessLogEntity.ts b/backend/src/migrations/1763724062000-CreateSecretAccessLogEntity.ts index 48fb6c399..ee4c22388 100644 --- a/backend/src/migrations/1763724062000-CreateSecretAccessLogEntity.ts +++ b/backend/src/migrations/1763724062000-CreateSecretAccessLogEntity.ts @@ -1,12 +1,14 @@ -import {MigrationInterface, QueryRunner} from "typeorm"; +import { MigrationInterface, QueryRunner } from 'typeorm'; export class CreateSecretAccessLogEntity1763724062000 implements MigrationInterface { - name = 'CreateSecretAccessLogEntity1763724062000' + name = 'CreateSecretAccessLogEntity1763724062000'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TYPE "secret_access_logs_action_enum" AS ENUM('create', 'view', 'copy', 'update', 'delete')`); + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `CREATE TYPE "secret_access_logs_action_enum" AS ENUM('create', 'view', 'copy', 'update', 'delete')`, + ); - await queryRunner.query(`CREATE TABLE "secret_access_logs" ( + await queryRunner.query(`CREATE TABLE "secret_access_logs" ( "id" uuid NOT NULL DEFAULT uuid_generate_v4(), "secretId" uuid NOT NULL, "userId" uuid NOT NULL, @@ -19,22 +21,25 @@ export class CreateSecretAccessLogEntity1763724062000 implements MigrationInterf CONSTRAINT "PK_secret_access_logs" PRIMARY KEY ("id") )`); - await queryRunner.query(`CREATE INDEX "IDX_secret_access_logs_secretId" ON "secret_access_logs" ("secretId")`); - await queryRunner.query(`CREATE INDEX "IDX_secret_access_logs_userId" ON "secret_access_logs" ("userId")`); - await queryRunner.query(`CREATE INDEX "IDX_secret_access_logs_accessedAt" ON "secret_access_logs" ("accessedAt")`); + await queryRunner.query(`CREATE INDEX "IDX_secret_access_logs_secretId" ON "secret_access_logs" ("secretId")`); + await queryRunner.query(`CREATE INDEX "IDX_secret_access_logs_userId" ON "secret_access_logs" ("userId")`); + await queryRunner.query(`CREATE INDEX "IDX_secret_access_logs_accessedAt" ON "secret_access_logs" ("accessedAt")`); - await queryRunner.query(`ALTER TABLE "secret_access_logs" ADD CONSTRAINT "FK_secret_access_logs_secretId" FOREIGN KEY ("secretId") REFERENCES "user_secrets"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - await queryRunner.query(`ALTER TABLE "secret_access_logs" ADD CONSTRAINT "FK_secret_access_logs_userId" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "secret_access_logs" DROP CONSTRAINT "FK_secret_access_logs_userId"`); - await queryRunner.query(`ALTER TABLE "secret_access_logs" DROP CONSTRAINT "FK_secret_access_logs_secretId"`); - await queryRunner.query(`DROP INDEX "IDX_secret_access_logs_accessedAt"`); - await queryRunner.query(`DROP INDEX "IDX_secret_access_logs_userId"`); - await queryRunner.query(`DROP INDEX "IDX_secret_access_logs_secretId"`); - await queryRunner.query(`DROP TABLE "secret_access_logs"`); - await queryRunner.query(`DROP TYPE "secret_access_logs_action_enum"`); - } + await queryRunner.query( + `ALTER TABLE "secret_access_logs" ADD CONSTRAINT "FK_secret_access_logs_secretId" FOREIGN KEY ("secretId") REFERENCES "user_secrets"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + await queryRunner.query( + `ALTER TABLE "secret_access_logs" ADD CONSTRAINT "FK_secret_access_logs_userId" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "secret_access_logs" DROP CONSTRAINT "FK_secret_access_logs_userId"`); + await queryRunner.query(`ALTER TABLE "secret_access_logs" DROP CONSTRAINT "FK_secret_access_logs_secretId"`); + await queryRunner.query(`DROP INDEX "IDX_secret_access_logs_accessedAt"`); + await queryRunner.query(`DROP INDEX "IDX_secret_access_logs_userId"`); + await queryRunner.query(`DROP INDEX "IDX_secret_access_logs_secretId"`); + await queryRunner.query(`DROP TABLE "secret_access_logs"`); + await queryRunner.query(`DROP TYPE "secret_access_logs_action_enum"`); + } } diff --git a/backend/src/migrations/1764239409303-AddSignInAuditEntity.ts b/backend/src/migrations/1764239409303-AddSignInAuditEntity.ts index 0c285a949..e95fc0b6f 100644 --- a/backend/src/migrations/1764239409303-AddSignInAuditEntity.ts +++ b/backend/src/migrations/1764239409303-AddSignInAuditEntity.ts @@ -1,25 +1,25 @@ import { MigrationInterface, QueryRunner } from 'typeorm'; export class AddSignInAuditEntity1764239409303 implements MigrationInterface { - name = 'AddSignInAuditEntity1764239409303'; + name = 'AddSignInAuditEntity1764239409303'; - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TYPE "public"."signInAudit_status_enum" AS ENUM('success', 'failed', 'blocked')`); - await queryRunner.query( - `CREATE TYPE "public"."signInAudit_signinmethod_enum" AS ENUM('email', 'google', 'github', 'saml', 'otp')`, - ); - await queryRunner.query( - `CREATE TABLE "signInAudit" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "email" character varying, "status" "public"."signInAudit_status_enum" NOT NULL DEFAULT 'success', "signInMethod" "public"."signInAudit_signinmethod_enum" NOT NULL DEFAULT 'email', "ipAddress" character varying, "userAgent" character varying, "failureReason" character varying, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "userId" uuid, CONSTRAINT "PK_7da6fabf99add8472fb25327a13" PRIMARY KEY ("id"))`, - ); - await queryRunner.query( - `ALTER TABLE "signInAudit" ADD CONSTRAINT "FK_f0574f10d690de5779e74563f8f" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, - ); - } + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TYPE "public"."signInAudit_status_enum" AS ENUM('success', 'failed', 'blocked')`); + await queryRunner.query( + `CREATE TYPE "public"."signInAudit_signinmethod_enum" AS ENUM('email', 'google', 'github', 'saml', 'otp')`, + ); + await queryRunner.query( + `CREATE TABLE "signInAudit" ("id" uuid NOT NULL DEFAULT uuid_generate_v4(), "email" character varying, "status" "public"."signInAudit_status_enum" NOT NULL DEFAULT 'success', "signInMethod" "public"."signInAudit_signinmethod_enum" NOT NULL DEFAULT 'email', "ipAddress" character varying, "userAgent" character varying, "failureReason" character varying, "createdAt" TIMESTAMP NOT NULL DEFAULT now(), "userId" uuid, CONSTRAINT "PK_7da6fabf99add8472fb25327a13" PRIMARY KEY ("id"))`, + ); + await queryRunner.query( + `ALTER TABLE "signInAudit" ADD CONSTRAINT "FK_f0574f10d690de5779e74563f8f" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE NO ACTION`, + ); + } - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "signInAudit" DROP CONSTRAINT "FK_f0574f10d690de5779e74563f8f"`); - await queryRunner.query(`DROP TABLE "signInAudit"`); - await queryRunner.query(`DROP TYPE "public"."signInAudit_signinmethod_enum"`); - await queryRunner.query(`DROP TYPE "public"."signInAudit_status_enum"`); - } + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "signInAudit" DROP CONSTRAINT "FK_f0574f10d690de5779e74563f8f"`); + await queryRunner.query(`DROP TABLE "signInAudit"`); + await queryRunner.query(`DROP TYPE "public"."signInAudit_signinmethod_enum"`); + await queryRunner.query(`DROP TYPE "public"."signInAudit_status_enum"`); + } } diff --git a/backend/src/selfhosted-operations/application/dto/create-initial-admin-user.dto.ts b/backend/src/selfhosted-operations/application/dto/create-initial-admin-user.dto.ts index f3e6a3f57..25d5e8791 100644 --- a/backend/src/selfhosted-operations/application/dto/create-initial-admin-user.dto.ts +++ b/backend/src/selfhosted-operations/application/dto/create-initial-admin-user.dto.ts @@ -2,16 +2,16 @@ import { ApiProperty } from '@nestjs/swagger'; import { IsEmail, IsNotEmpty, IsString, MaxLength, MinLength } from 'class-validator'; export class CreateInitialUserDto { - @ApiProperty({ description: 'User email' }) - @IsNotEmpty() - @IsString() - @IsEmail() - readonly email: string; + @ApiProperty({ description: 'User email' }) + @IsNotEmpty() + @IsString() + @IsEmail() + readonly email: string; - @ApiProperty({ description: 'Admin user password' }) - @IsNotEmpty() - @IsString() - @MinLength(8) - @MaxLength(255) - readonly password: string; + @ApiProperty({ description: 'Admin user password' }) + @IsNotEmpty() + @IsString() + @MinLength(8) + @MaxLength(255) + readonly password: string; } diff --git a/backend/src/selfhosted-operations/application/use-cases/create-initial-user.use.case.ts b/backend/src/selfhosted-operations/application/use-cases/create-initial-user.use.case.ts index de72ab898..23542cf96 100644 --- a/backend/src/selfhosted-operations/application/use-cases/create-initial-user.use.case.ts +++ b/backend/src/selfhosted-operations/application/use-cases/create-initial-user.use.case.ts @@ -2,17 +2,17 @@ import { BadRequestException, Inject, Injectable } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; -import { SimpleFoundUserInfoDs } from '../../../entities/user/dto/found-user.dto.js'; -import { ICreateInitialUserUseCase } from './selfhosted-use-cases.interfaces.js'; -import { CreateInitialUserDs } from '../data-structures/create-initial-user.ds.js'; -import { isSaaS } from '../../../helpers/app/is-saas.js'; -import { Messages } from '../../../exceptions/text/messages.js'; +import { CompanyInfoEntity } from '../../../entities/company-info/company-info.entity.js'; import { RegisterUserDs } from '../../../entities/user/application/data-structures/register-user-ds.js'; +import { SimpleFoundUserInfoDs } from '../../../entities/user/dto/found-user.dto.js'; import { UserRoleEnum } from '../../../entities/user/enums/user-role.enum.js'; +import { buildSimpleUserInfoDs } from '../../../entities/user/utils/build-created-user.ds.js'; import { buildRegisteringUser } from '../../../entities/user/utils/build-registering-user.util.js'; -import { CompanyInfoEntity } from '../../../entities/company-info/company-info.entity.js'; +import { Messages } from '../../../exceptions/text/messages.js'; +import { isSaaS } from '../../../helpers/app/is-saas.js'; import { Encryptor } from '../../../helpers/encryption/encryptor.js'; -import { buildSimpleUserInfoDs } from '../../../entities/user/utils/build-created-user.ds.js'; +import { CreateInitialUserDs } from '../data-structures/create-initial-user.ds.js'; +import { ICreateInitialUserUseCase } from './selfhosted-use-cases.interfaces.js'; @Injectable() export class CreateInitialUserUseCase diff --git a/backend/src/selfhosted-operations/application/use-cases/is-configured.use.case.ts b/backend/src/selfhosted-operations/application/use-cases/is-configured.use.case.ts index ab3a234b5..119934a2f 100644 --- a/backend/src/selfhosted-operations/application/use-cases/is-configured.use.case.ts +++ b/backend/src/selfhosted-operations/application/use-cases/is-configured.use.case.ts @@ -2,9 +2,9 @@ import { Inject, Injectable } from '@nestjs/common'; import AbstractUseCase from '../../../common/abstract-use.case.js'; import { IGlobalDatabaseContext } from '../../../common/application/global-database-context.interface.js'; import { BaseType } from '../../../common/data-injection.tokens.js'; +import { isSaaS } from '../../../helpers/app/is-saas.js'; import { IsConfiguredRo } from '../responce-objects/is-configured.ro.js'; import { IIsConfiguredUseCase } from './selfhosted-use-cases.interfaces.js'; -import { isSaaS } from '../../../helpers/app/is-saas.js'; @Injectable() export class IsConfiguredUseCase extends AbstractUseCase implements IIsConfiguredUseCase { diff --git a/backend/src/selfhosted-operations/application/use-cases/selfhosted-use-cases.interfaces.ts b/backend/src/selfhosted-operations/application/use-cases/selfhosted-use-cases.interfaces.ts index 8fa88ab29..ce96c69af 100644 --- a/backend/src/selfhosted-operations/application/use-cases/selfhosted-use-cases.interfaces.ts +++ b/backend/src/selfhosted-operations/application/use-cases/selfhosted-use-cases.interfaces.ts @@ -1,7 +1,7 @@ -import { InTransactionEnum } from '../../../enums/index.js'; import { SimpleFoundUserInfoDs } from '../../../entities/user/dto/found-user.dto.js'; -import { IsConfiguredRo } from '../responce-objects/is-configured.ro.js'; +import { InTransactionEnum } from '../../../enums/index.js'; import { CreateInitialUserDs } from '../data-structures/create-initial-user.ds.js'; +import { IsConfiguredRo } from '../responce-objects/is-configured.ro.js'; export interface IIsConfiguredUseCase { execute(inputData: undefined, inTransaction: InTransactionEnum): Promise; diff --git a/backend/src/selfhosted-operations/selfhosted-operations.controller.ts b/backend/src/selfhosted-operations/selfhosted-operations.controller.ts index cacc28bdb..fb23a1f14 100644 --- a/backend/src/selfhosted-operations/selfhosted-operations.controller.ts +++ b/backend/src/selfhosted-operations/selfhosted-operations.controller.ts @@ -1,15 +1,15 @@ import { Body, Controller, Get, HttpStatus, Inject, Post, UseInterceptors } from '@nestjs/common'; import { ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger'; +import { UseCaseType } from '../common/data-injection.tokens.js'; +import { SimpleFoundUserInfoDs } from '../entities/user/dto/found-user.dto.js'; +import { InTransactionEnum } from '../enums/index.js'; import { SentryInterceptor } from '../interceptors/index.js'; -import { IsConfiguredRo } from './application/responce-objects/is-configured.ro.js'; import { CreateInitialUserDto } from './application/dto/create-initial-admin-user.dto.js'; -import { SimpleFoundUserInfoDs } from '../entities/user/dto/found-user.dto.js'; -import { UseCaseType } from '../common/data-injection.tokens.js'; +import { IsConfiguredRo } from './application/responce-objects/is-configured.ro.js'; import { - IIsConfiguredUseCase, ICreateInitialUserUseCase, + IIsConfiguredUseCase, } from './application/use-cases/selfhosted-use-cases.interfaces.js'; -import { InTransactionEnum } from '../enums/index.js'; @UseInterceptors(SentryInterceptor) @Controller('selfhosted') diff --git a/backend/src/selfhosted-operations/selhosted-operations.module.ts b/backend/src/selfhosted-operations/selhosted-operations.module.ts index a0ba54796..bc8ffcf22 100644 --- a/backend/src/selfhosted-operations/selhosted-operations.module.ts +++ b/backend/src/selfhosted-operations/selhosted-operations.module.ts @@ -1,13 +1,13 @@ import { DynamicModule, Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; -import { UserEntity } from '../entities/user/user.entity.js'; -import { CompanyInfoEntity } from '../entities/company-info/company-info.entity.js'; -import { SelfHostedOperationsController } from './selfhosted-operations.controller.js'; import { GlobalDatabaseContext } from '../common/application/global-database-context.js'; import { BaseType, UseCaseType } from '../common/data-injection.tokens.js'; -import { IsConfiguredUseCase } from './application/use-cases/is-configured.use.case.js'; -import { CreateInitialUserUseCase } from './application/use-cases/create-initial-user.use.case.js'; +import { CompanyInfoEntity } from '../entities/company-info/company-info.entity.js'; +import { UserEntity } from '../entities/user/user.entity.js'; import { isSaaS } from '../helpers/app/is-saas.js'; +import { CreateInitialUserUseCase } from './application/use-cases/create-initial-user.use.case.js'; +import { IsConfiguredUseCase } from './application/use-cases/is-configured.use.case.js'; +import { SelfHostedOperationsController } from './selfhosted-operations.controller.js'; @Module({}) export class SelfHostedOperationsModule { diff --git a/backend/src/shared/config/config.service.ts b/backend/src/shared/config/config.service.ts index 773dbfc16..988a66bc7 100644 --- a/backend/src/shared/config/config.service.ts +++ b/backend/src/shared/config/config.service.ts @@ -1,133 +1,134 @@ -import { join } from 'path'; +import dotenv from 'dotenv'; +import path, { join } from 'path'; +import parse from 'pg-connection-string'; import { DataSourceOptions } from 'typeorm'; -import path from 'path'; import { fileURLToPath } from 'url'; -import parse from 'pg-connection-string'; -import dotenv from 'dotenv'; + const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); + import { uuid_ossp } from '@electric-sql/pglite/contrib/uuid_ossp'; -import { PGliteDriver } from 'typeorm-pglite'; import fs from 'fs'; +import { PGliteDriver } from 'typeorm-pglite'; import { isTest } from '../../helpers/app/is-test.js'; dotenv.config(); class ConfigService { - constructor(private env: { [k: string]: string | undefined }) {} - - private getValue(key: string, throwOnMissing = !this.isTestEnvironment()): string { - // eslint-disable-next-line security/detect-object-injection - const value = this.env[key]; - if (!value && throwOnMissing) { - throw new Error(`config error - missing env.${key}`); - } - - return value; - } - - public ensureValues(keys: Array) { - const isTest = this.isTestEnvironment(); - if (isTest) { - console.info('Running test environment'); - } - keys.forEach((k) => this.getValue(k, !isTest)); - return this; - } - - public getPort() { - return this.getValue('PORT', !this.isTestEnvironment()); - } - - public isTestEnvironment(): boolean { - return process.env.NODE_ENV === 'test'; - } - - public getTypeOrmConfig(): DataSourceOptions { - const pgLiteFolderPath = process.env.PGLITE_FOLDER_PATH; - - let pgLiteDriver = null; - let connectionParams = {}; - - if (pgLiteFolderPath && pgLiteFolderPath.length > 0) { - const fullPath = isTest() - ? path.join(process.cwd(), ...pgLiteFolderPath.split('/')) - : path.join(__dirname, '..', '..', '..', pgLiteFolderPath); - console.info('\nPg Lite Folder Patch: ', pgLiteFolderPath, '\n'); - const resolvedPath = path.resolve(fullPath); - try { - fs.accessSync(resolvedPath, fs.constants.F_OK); - console.log('PGLite directory exists'); - try { - fs.accessSync(resolvedPath, fs.constants.W_OK); - console.log('PGLite directory is writable'); - } catch (writeError) { - console.warn('PGLite directory exists but may not be writable:', writeError.message); - } - } catch (error) { - console.log('PGLite directory does not exist, will be created by PGLite', error); - } - - pgLiteDriver = new PGliteDriver({ - extensions: { uuid_ossp }, - dataDir: path.resolve(resolvedPath), - }).driver; - } else { - connectionParams = this.parseTypeORMUrl(this.getValue('DATABASE_URL')); - } - - const newTypeOrmProdConfig: DataSourceOptions = { - type: 'postgres', - ...connectionParams, - entities: [join(__dirname, '..', '..', '**', '*.entity.{ts,js}')], - migrations: [join(__dirname, '..', '..', 'migrations', '*.{ts,js}')], - synchronize: false, - migrationsRun: false, - extra: { - max: 20, - idle_in_transaction_session_timeout: 20 * 1000, - }, - driver: pgLiteDriver ? pgLiteDriver : undefined, - }; - - const newTypeOrmTestConfig: DataSourceOptions = { - type: 'postgres', - ...connectionParams, - entities: [join(__dirname, '..', '..', '**', '*.entity.{ts,js}')], - migrations: [join(__dirname, '..', '..', 'migrations', '*.{ts,js}')], - synchronize: false, - migrationsRun: false, - logging: false, - extra: { - max: 10, - }, - logger: 'advanced-console', - driver: pgLiteDriver ? pgLiteDriver : undefined, - }; - - return this.isTestEnvironment() ? newTypeOrmTestConfig : newTypeOrmProdConfig; - } - - private parseTypeORMUrl(url: string): { - host: string; - port: number; - username: string; - password: string; - database: string; - ssl: any; - } { - const parsingResult = parse.parse(url); - const { host, port, user, password, database, ssl } = parsingResult; - - return { - host, - port: parseInt(port, 10), - username: user, - password, - database, - ssl, - }; - } + constructor(private env: { [k: string]: string | undefined }) {} + + private getValue(key: string, throwOnMissing = !this.isTestEnvironment()): string { + // eslint-disable-next-line security/detect-object-injection + const value = this.env[key]; + if (!value && throwOnMissing) { + throw new Error(`config error - missing env.${key}`); + } + + return value; + } + + public ensureValues(keys: Array) { + const isTest = this.isTestEnvironment(); + if (isTest) { + console.info('Running test environment'); + } + keys.forEach((k) => this.getValue(k, !isTest)); + return this; + } + + public getPort() { + return this.getValue('PORT', !this.isTestEnvironment()); + } + + public isTestEnvironment(): boolean { + return process.env.NODE_ENV === 'test'; + } + + public getTypeOrmConfig(): DataSourceOptions { + const pgLiteFolderPath = process.env.PGLITE_FOLDER_PATH; + + let pgLiteDriver = null; + let connectionParams = {}; + + if (pgLiteFolderPath && pgLiteFolderPath.length > 0) { + const fullPath = isTest() + ? path.join(process.cwd(), ...pgLiteFolderPath.split('/')) + : path.join(__dirname, '..', '..', '..', pgLiteFolderPath); + console.info('\nPg Lite Folder Patch: ', pgLiteFolderPath, '\n'); + const resolvedPath = path.resolve(fullPath); + try { + fs.accessSync(resolvedPath, fs.constants.F_OK); + console.log('PGLite directory exists'); + try { + fs.accessSync(resolvedPath, fs.constants.W_OK); + console.log('PGLite directory is writable'); + } catch (writeError) { + console.warn('PGLite directory exists but may not be writable:', writeError.message); + } + } catch (error) { + console.log('PGLite directory does not exist, will be created by PGLite', error); + } + + pgLiteDriver = new PGliteDriver({ + extensions: { uuid_ossp }, + dataDir: path.resolve(resolvedPath), + }).driver; + } else { + connectionParams = this.parseTypeORMUrl(this.getValue('DATABASE_URL')); + } + + const newTypeOrmProdConfig: DataSourceOptions = { + type: 'postgres', + ...connectionParams, + entities: [join(__dirname, '..', '..', '**', '*.entity.{ts,js}')], + migrations: [join(__dirname, '..', '..', 'migrations', '*.{ts,js}')], + synchronize: false, + migrationsRun: false, + extra: { + max: 20, + idle_in_transaction_session_timeout: 20 * 1000, + }, + driver: pgLiteDriver ? pgLiteDriver : undefined, + }; + + const newTypeOrmTestConfig: DataSourceOptions = { + type: 'postgres', + ...connectionParams, + entities: [join(__dirname, '..', '..', '**', '*.entity.{ts,js}')], + migrations: [join(__dirname, '..', '..', 'migrations', '*.{ts,js}')], + synchronize: false, + migrationsRun: false, + logging: false, + extra: { + max: 10, + }, + logger: 'advanced-console', + driver: pgLiteDriver ? pgLiteDriver : undefined, + }; + + return this.isTestEnvironment() ? newTypeOrmTestConfig : newTypeOrmProdConfig; + } + + private parseTypeORMUrl(url: string): { + host: string; + port: number; + username: string; + password: string; + database: string; + ssl: any; + } { + const parsingResult = parse.parse(url); + const { host, port, user, password, database, ssl } = parsingResult; + + return { + host, + port: parseInt(port, 10), + username: user, + password, + database, + ssl, + }; + } } const configService = new ConfigService(process.env).ensureValues([]); diff --git a/backend/src/shared/database/database.module.ts b/backend/src/shared/database/database.module.ts index 928de4d33..632c8b1be 100644 --- a/backend/src/shared/database/database.module.ts +++ b/backend/src/shared/database/database.module.ts @@ -5,8 +5,8 @@ import { databaseProviders } from './database.providers.js'; @Global() @Module({ - imports: [TypeOrmModule.forRoot(configService.getTypeOrmConfig())], - providers: [...databaseProviders], - exports: [...databaseProviders], + imports: [TypeOrmModule.forRoot(configService.getTypeOrmConfig())], + providers: [...databaseProviders], + exports: [...databaseProviders], }) export class DatabaseModule {} diff --git a/backend/src/shared/database/database.providers.ts b/backend/src/shared/database/database.providers.ts index beaaca62e..2836d0a1b 100644 --- a/backend/src/shared/database/database.providers.ts +++ b/backend/src/shared/database/database.providers.ts @@ -1,19 +1,20 @@ import { DataSource } from 'typeorm'; -import { configService } from '../config/config.service.js'; import { BaseType } from '../../common/data-injection.tokens.js'; +import { configService } from '../config/config.service.js'; + let appDataSourceCache: DataSource = null; export const databaseProviders = [ - { - provide: BaseType.DATA_SOURCE, - useFactory: async () => { - if (appDataSourceCache?.isInitialized) { - return appDataSourceCache; - } - const AppDataSource = new DataSource(configService.getTypeOrmConfig()); - const dataSource = await AppDataSource.initialize(); - appDataSourceCache = dataSource; - return dataSource; - }, - }, + { + provide: BaseType.DATA_SOURCE, + useFactory: async () => { + if (appDataSourceCache?.isInitialized) { + return appDataSourceCache; + } + const AppDataSource = new DataSource(configService.getTypeOrmConfig()); + const dataSource = await AppDataSource.initialize(); + appDataSourceCache = dataSource; + return dataSource; + }, + }, ]; diff --git a/backend/src/shared/database/database.service.ts b/backend/src/shared/database/database.service.ts index e346691b4..e17146cbf 100644 --- a/backend/src/shared/database/database.service.ts +++ b/backend/src/shared/database/database.service.ts @@ -2,33 +2,33 @@ import { InjectDataSource } from '@nestjs/typeorm'; import { DataSource } from 'typeorm'; export class DatabaseService { - constructor( - @InjectDataSource() - private dataSource: DataSource, - ) {} + constructor( + @InjectDataSource() + private dataSource: DataSource, + ) {} - public getDataSource(): DataSource { - return this.dataSource; - } + public getDataSource(): DataSource { + return this.dataSource; + } - public async dropDatabase() { - if (process.env.NODE_ENV !== 'test') { - throw new Error('This method only for testing'); - } - try { - await this.dataSource.dropDatabase(); - await this.dataSource.synchronize(); - } catch (e) { - console.error(e); - } - return; - } + public async dropDatabase() { + if (process.env.NODE_ENV !== 'test') { + throw new Error('This method only for testing'); + } + try { + await this.dataSource.dropDatabase(); + await this.dataSource.synchronize(); + } catch (e) { + console.error(e); + } + return; + } - public async closeConnection() { - try { - return await this.dataSource.destroy(); - } catch (e) { - console.error(e); - } - } + public async closeConnection() { + try { + return await this.dataSource.destroy(); + } catch (e) { + console.error(e); + } + } } diff --git a/backend/src/shared/services/turnstile.service.ts b/backend/src/shared/services/turnstile.service.ts index 42aebdc97..26d82e0af 100644 --- a/backend/src/shared/services/turnstile.service.ts +++ b/backend/src/shared/services/turnstile.service.ts @@ -1,7 +1,7 @@ import { BadRequestException, Injectable } from '@nestjs/common'; import axios from 'axios'; -import { isTest } from '../../helpers/app/is-test.js'; import { isSaaS } from '../../helpers/app/is-saas.js'; +import { isTest } from '../../helpers/app/is-test.js'; interface TurnstileVerifyResponse { success: boolean; diff --git a/backend/src/types/pglite-contrib.d.ts b/backend/src/types/pglite-contrib.d.ts index d7d3c9154..acf5c51f5 100644 --- a/backend/src/types/pglite-contrib.d.ts +++ b/backend/src/types/pglite-contrib.d.ts @@ -1,3 +1,3 @@ declare module '@electric-sql/pglite/contrib/uuid_ossp' { - export const uuid_ossp: any; + export const uuid_ossp: any; } diff --git a/backend/src/use-cases-app/get-hello.use.case.ts b/backend/src/use-cases-app/get-hello.use.case.ts index e365e9043..a4a1b6672 100644 --- a/backend/src/use-cases-app/get-hello.use.case.ts +++ b/backend/src/use-cases-app/get-hello.use.case.ts @@ -1,28 +1,28 @@ import { HttpException, HttpStatus, Inject, Injectable, Scope } from '@nestjs/common'; import AbstractUseCase from '../common/abstract-use.case.js'; -import { IGetHello } from './use-cases-app.interface.js'; -import { BaseType } from '../common/data-injection.tokens.js'; import { IGlobalDatabaseContext } from '../common/application/global-database-context.interface.js'; +import { BaseType } from '../common/data-injection.tokens.js'; +import { IGetHello } from './use-cases-app.interface.js'; @Injectable({ scope: Scope.REQUEST }) export class GetHelloUseCase extends AbstractUseCase implements IGetHello { - constructor( - @Inject(BaseType.GLOBAL_DB_CONTEXT) - protected _dbContext: IGlobalDatabaseContext, - ) { - super(); - } + constructor( + @Inject(BaseType.GLOBAL_DB_CONTEXT) + protected _dbContext: IGlobalDatabaseContext, + ) { + super(); + } - protected async implementation(): Promise { - const result = await this._dbContext.userRepository.getTrue(); - if (result) { - return 'Hello World!'; - } - throw new HttpException( - { - message: 'Database not alive', - }, - HttpStatus.GATEWAY_TIMEOUT, - ); - } + protected async implementation(): Promise { + const result = await this._dbContext.userRepository.getTrue(); + if (result) { + return 'Hello World!'; + } + throw new HttpException( + { + message: 'Database not alive', + }, + HttpStatus.GATEWAY_TIMEOUT, + ); + } } diff --git a/backend/src/use-cases-app/use-cases-app.interface.ts b/backend/src/use-cases-app/use-cases-app.interface.ts index 924702b11..7da913572 100644 --- a/backend/src/use-cases-app/use-cases-app.interface.ts +++ b/backend/src/use-cases-app/use-cases-app.interface.ts @@ -1,5 +1,5 @@ import { InTransactionEnum } from '../enums/index.js'; export interface IGetHello { - execute(inputData: undefined, inTransaction: InTransactionEnum): Promise; + execute(inputData: undefined, inTransaction: InTransactionEnum): Promise; } diff --git a/backend/test/ava-tests/complex-table-tests/complex-ibmdb2-table-e2e.test.ts b/backend/test/ava-tests/complex-table-tests/complex-ibmdb2-table-e2e.test.ts index 4c3a6c1cc..1271e989f 100644 --- a/backend/test/ava-tests/complex-table-tests/complex-ibmdb2-table-e2e.test.ts +++ b/backend/test/ava-tests/complex-table-tests/complex-ibmdb2-table-e2e.test.ts @@ -17,8 +17,8 @@ import { MockFactory } from '../../mock.factory.js'; import { getTestData } from '../../utils/get-test-data.js'; import { registerUserAndReturnUserInfo } from '../../utils/register-user-and-return-user-info.js'; import { - createTestIBMDB2TablesWithComplexPFKeys, - createTestIBMDB2TablesWithSimplePFKeys, + createTestIBMDB2TablesWithComplexPFKeys, + createTestIBMDB2TablesWithSimplePFKeys, } from '../../utils/test-utilities/create-test-ibmdb2-tables.js'; import { TestUtils } from '../../utils/test.utils.js'; @@ -35,198 +35,198 @@ let testTablesCompositeKeysData: TableCreationResult; let testTablesSimpleKeysData: TableCreationResult; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication() as any; - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); - - testTablesCompositeKeysData = await createTestIBMDB2TablesWithComplexPFKeys(connectionToTestDB); - testTablesSimpleKeysData = await createTestIBMDB2TablesWithSimplePFKeys(connectionToTestDB); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication() as any; + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); + + testTablesCompositeKeysData = await createTestIBMDB2TablesWithComplexPFKeys(connectionToTestDB); + testTablesSimpleKeysData = await createTestIBMDB2TablesWithSimplePFKeys(connectionToTestDB); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); export type TableCreationResult = { - main_table: { - table_name: string; - column_names: string[]; - foreign_key_column_names: string[]; - binary_column_names: string[]; - primary_key_column_names: string[]; - }; - first_referenced_table: { - table_name: string; - column_names: string[]; - primary_key_column_names: string[]; - }; - second_referenced_table: { - table_name: string; - column_names: string[]; - primary_key_column_names: string[]; - foreign_key_column_names: string[]; - }; + main_table: { + table_name: string; + column_names: string[]; + foreign_key_column_names: string[]; + binary_column_names: string[]; + primary_key_column_names: string[]; + }; + first_referenced_table: { + table_name: string; + column_names: string[]; + primary_key_column_names: string[]; + }; + second_referenced_table: { + table_name: string; + column_names: string[]; + primary_key_column_names: string[]; + foreign_key_column_names: string[]; + }; }; // GET /connection/tables/:slug test.serial( - `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has composite structure`, - async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const { main_table, first_referenced_table, second_referenced_table } = testTablesCompositeKeysData; - - const getMainTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); - t.is(getMainTableRowsResponse.status, 200); - - const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); - t.is(getFirstReferencedTableRowsResponse.status, 200); - - const firstReturnedRows = getFirstReferencedTableRowsRO.rows; - - for (const row of firstReturnedRows) { - t.is(typeof row.ORDER_ID, 'object'); - t.truthy(Object.hasOwn(row.ORDER_ID, 'ORDER_ID')); - t.truthy(row.ORDER_ID.ORDER_ID); - t.truthy(typeof row.ORDER_ID.ORDER_ID === 'number'); - t.is(typeof row.CUSTOMER_ID, 'object'); - t.truthy(Object.hasOwn(row.CUSTOMER_ID, 'CUSTOMER_ID')); - t.truthy(row.CUSTOMER_ID.CUSTOMER_ID); - t.truthy(typeof row.CUSTOMER_ID.CUSTOMER_ID === 'number'); - } - - const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); - t.is(getSecondReferencedTableRowsResponse.status, 200); - const secondReturnedRows = getSecondReferencedTableRowsRO.rows; - for (const row of secondReturnedRows) { - t.is(typeof row.ORDER_ID, 'object'); - t.truthy(Object.hasOwn(row.ORDER_ID, 'ORDER_ID')); - t.truthy(row.ORDER_ID.ORDER_ID); - t.truthy(typeof row.ORDER_ID.ORDER_ID === 'number'); - t.is(typeof row.CUSTOMER_ID, 'object'); - t.truthy(Object.hasOwn(row.CUSTOMER_ID, 'CUSTOMER_ID')); - t.truthy(row.CUSTOMER_ID.CUSTOMER_ID); - t.truthy(typeof row.CUSTOMER_ID.CUSTOMER_ID === 'number'); - } - } catch (e) { - console.error(e); - throw e; - } - }, + `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has composite structure`, + async (t) => { + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const { main_table, first_referenced_table, second_referenced_table } = testTablesCompositeKeysData; + + const getMainTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); + t.is(getMainTableRowsResponse.status, 200); + + const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); + t.is(getFirstReferencedTableRowsResponse.status, 200); + + const firstReturnedRows = getFirstReferencedTableRowsRO.rows; + + for (const row of firstReturnedRows) { + t.is(typeof row.ORDER_ID, 'object'); + t.truthy(Object.hasOwn(row.ORDER_ID, 'ORDER_ID')); + t.truthy(row.ORDER_ID.ORDER_ID); + t.truthy(typeof row.ORDER_ID.ORDER_ID === 'number'); + t.is(typeof row.CUSTOMER_ID, 'object'); + t.truthy(Object.hasOwn(row.CUSTOMER_ID, 'CUSTOMER_ID')); + t.truthy(row.CUSTOMER_ID.CUSTOMER_ID); + t.truthy(typeof row.CUSTOMER_ID.CUSTOMER_ID === 'number'); + } + + const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); + t.is(getSecondReferencedTableRowsResponse.status, 200); + const secondReturnedRows = getSecondReferencedTableRowsRO.rows; + for (const row of secondReturnedRows) { + t.is(typeof row.ORDER_ID, 'object'); + t.truthy(Object.hasOwn(row.ORDER_ID, 'ORDER_ID')); + t.truthy(row.ORDER_ID.ORDER_ID); + t.truthy(typeof row.ORDER_ID.ORDER_ID === 'number'); + t.is(typeof row.CUSTOMER_ID, 'object'); + t.truthy(Object.hasOwn(row.CUSTOMER_ID, 'CUSTOMER_ID')); + t.truthy(row.CUSTOMER_ID.CUSTOMER_ID); + t.truthy(typeof row.CUSTOMER_ID.CUSTOMER_ID === 'number'); + } + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has simple structure`, - async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const { main_table, first_referenced_table, second_referenced_table } = testTablesSimpleKeysData; - - const getMainTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); - t.is(getMainTableRowsResponse.status, 200); - - const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); - t.is(getFirstReferencedTableRowsResponse.status, 200); - - const firstReturnedRows = getFirstReferencedTableRowsRO.rows; - - for (const element of firstReturnedRows) { - t.is(typeof element.ORDER_ID, 'object'); - t.truthy(Object.hasOwn(element.ORDER_ID, 'ORDER_ID')); - t.truthy(element.ORDER_ID.ORDER_ID); - t.truthy(typeof element.ORDER_ID.ORDER_ID === 'number'); - } - - const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); - t.is(getSecondReferencedTableRowsResponse.status, 200); - - const secondReturnedRows = getSecondReferencedTableRowsRO.rows; - for (const element of secondReturnedRows) { - t.is(typeof element.ORDER_ID, 'object'); - t.truthy(Object.hasOwn(element.ORDER_ID, 'ORDER_ID')); - t.truthy(element.ORDER_ID.ORDER_ID); - t.truthy(typeof element.ORDER_ID.ORDER_ID === 'number'); - } - } catch (e) { - console.error(e); - throw e; - } - }, + `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has simple structure`, + async (t) => { + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const { main_table, first_referenced_table, second_referenced_table } = testTablesSimpleKeysData; + + const getMainTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); + t.is(getMainTableRowsResponse.status, 200); + + const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); + t.is(getFirstReferencedTableRowsResponse.status, 200); + + const firstReturnedRows = getFirstReferencedTableRowsRO.rows; + + for (const element of firstReturnedRows) { + t.is(typeof element.ORDER_ID, 'object'); + t.truthy(Object.hasOwn(element.ORDER_ID, 'ORDER_ID')); + t.truthy(element.ORDER_ID.ORDER_ID); + t.truthy(typeof element.ORDER_ID.ORDER_ID === 'number'); + } + + const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); + t.is(getSecondReferencedTableRowsResponse.status, 200); + + const secondReturnedRows = getSecondReferencedTableRowsRO.rows; + for (const element of secondReturnedRows) { + t.is(typeof element.ORDER_ID, 'object'); + t.truthy(Object.hasOwn(element.ORDER_ID, 'ORDER_ID')); + t.truthy(element.ORDER_ID.ORDER_ID); + t.truthy(typeof element.ORDER_ID.ORDER_ID === 'number'); + } + } catch (e) { + console.error(e); + throw e; + } + }, ); diff --git a/backend/test/ava-tests/complex-table-tests/complex-mssql-table-e2e.test.ts b/backend/test/ava-tests/complex-table-tests/complex-mssql-table-e2e.test.ts index 0c2443461..dc115c2e4 100644 --- a/backend/test/ava-tests/complex-table-tests/complex-mssql-table-e2e.test.ts +++ b/backend/test/ava-tests/complex-table-tests/complex-mssql-table-e2e.test.ts @@ -17,8 +17,8 @@ import { MockFactory } from '../../mock.factory.js'; import { getTestData } from '../../utils/get-test-data.js'; import { registerUserAndReturnUserInfo } from '../../utils/register-user-and-return-user-info.js'; import { - createTestTablesWithComplexPFKeys, - createTestTablesWithSimplePFKeys, + createTestTablesWithComplexPFKeys, + createTestTablesWithSimplePFKeys, } from '../../utils/test-utilities/create-test-postgres-tables.js'; import { TestUtils } from '../../utils/test.utils.js'; @@ -35,198 +35,198 @@ let testTablesCompositeKeysData: TableCreationResult; let testTablesSimpleKeysData: TableCreationResult; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication() as any; - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); - - testTablesCompositeKeysData = await createTestTablesWithComplexPFKeys(connectionToTestDB); - testTablesSimpleKeysData = await createTestTablesWithSimplePFKeys(connectionToTestDB); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication() as any; + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); + + testTablesCompositeKeysData = await createTestTablesWithComplexPFKeys(connectionToTestDB); + testTablesSimpleKeysData = await createTestTablesWithSimplePFKeys(connectionToTestDB); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); export type TableCreationResult = { - main_table: { - table_name: string; - column_names: string[]; - foreign_key_column_names: string[]; - binary_column_names: string[]; - primary_key_column_names: string[]; - }; - first_referenced_table: { - table_name: string; - column_names: string[]; - primary_key_column_names: string[]; - }; - second_referenced_table: { - table_name: string; - column_names: string[]; - primary_key_column_names: string[]; - foreign_key_column_names: string[]; - }; + main_table: { + table_name: string; + column_names: string[]; + foreign_key_column_names: string[]; + binary_column_names: string[]; + primary_key_column_names: string[]; + }; + first_referenced_table: { + table_name: string; + column_names: string[]; + primary_key_column_names: string[]; + }; + second_referenced_table: { + table_name: string; + column_names: string[]; + primary_key_column_names: string[]; + foreign_key_column_names: string[]; + }; }; // GET /connection/tables/:slug test.serial( - `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has composite structure`, - async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const { main_table, first_referenced_table, second_referenced_table } = testTablesCompositeKeysData; - - const getMainTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); - t.is(getMainTableRowsResponse.status, 200); - - const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); - t.is(getFirstReferencedTableRowsResponse.status, 200); - - const firstReturnedRows = getFirstReferencedTableRowsRO.rows; - - for (const row of firstReturnedRows) { - t.is(typeof row.order_id, 'object'); - t.truthy(Object.hasOwn(row.order_id, 'order_id')); - t.truthy(row.order_id.order_id); - t.truthy(typeof row.order_id.order_id === 'number'); - t.is(typeof row.customer_id, 'object'); - t.truthy(Object.hasOwn(row.customer_id, 'customer_id')); - t.truthy(row.customer_id.customer_id); - t.truthy(typeof row.customer_id.customer_id === 'number'); - } - - const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); - t.is(getSecondReferencedTableRowsResponse.status, 200); - const secondReturnedRows = getSecondReferencedTableRowsRO.rows; - for (const row of secondReturnedRows) { - t.is(typeof row.order_id, 'object'); - t.truthy(Object.hasOwn(row.order_id, 'order_id')); - t.truthy(row.order_id.order_id); - t.truthy(typeof row.order_id.order_id === 'number'); - t.is(typeof row.customer_id, 'object'); - t.truthy(Object.hasOwn(row.customer_id, 'customer_id')); - t.truthy(row.customer_id.customer_id); - t.truthy(typeof row.customer_id.customer_id === 'number'); - } - } catch (e) { - console.error(e); - throw e; - } - }, + `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has composite structure`, + async (t) => { + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const { main_table, first_referenced_table, second_referenced_table } = testTablesCompositeKeysData; + + const getMainTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); + t.is(getMainTableRowsResponse.status, 200); + + const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); + t.is(getFirstReferencedTableRowsResponse.status, 200); + + const firstReturnedRows = getFirstReferencedTableRowsRO.rows; + + for (const row of firstReturnedRows) { + t.is(typeof row.order_id, 'object'); + t.truthy(Object.hasOwn(row.order_id, 'order_id')); + t.truthy(row.order_id.order_id); + t.truthy(typeof row.order_id.order_id === 'number'); + t.is(typeof row.customer_id, 'object'); + t.truthy(Object.hasOwn(row.customer_id, 'customer_id')); + t.truthy(row.customer_id.customer_id); + t.truthy(typeof row.customer_id.customer_id === 'number'); + } + + const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); + t.is(getSecondReferencedTableRowsResponse.status, 200); + const secondReturnedRows = getSecondReferencedTableRowsRO.rows; + for (const row of secondReturnedRows) { + t.is(typeof row.order_id, 'object'); + t.truthy(Object.hasOwn(row.order_id, 'order_id')); + t.truthy(row.order_id.order_id); + t.truthy(typeof row.order_id.order_id === 'number'); + t.is(typeof row.customer_id, 'object'); + t.truthy(Object.hasOwn(row.customer_id, 'customer_id')); + t.truthy(row.customer_id.customer_id); + t.truthy(typeof row.customer_id.customer_id === 'number'); + } + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has simple structure`, - async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const { main_table, first_referenced_table, second_referenced_table } = testTablesSimpleKeysData; - - const getMainTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); - t.is(getMainTableRowsResponse.status, 200); - - const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); - t.is(getFirstReferencedTableRowsResponse.status, 200); - - const firstReturnedRows = getFirstReferencedTableRowsRO.rows; - - for (const element of firstReturnedRows) { - t.is(typeof element.customer_id, 'object'); - t.truthy(Object.hasOwn(element.customer_id, 'customer_id')); - t.truthy(element.customer_id.customer_id); - t.truthy(typeof element.customer_id.customer_id === 'number'); - } - - const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); - t.is(getSecondReferencedTableRowsResponse.status, 200); - - const secondReturnedRows = getSecondReferencedTableRowsRO.rows; - for (const element of secondReturnedRows) { - t.is(typeof element.order_id, 'object'); - t.truthy(Object.hasOwn(element.order_id, 'order_id')); - t.truthy(element.order_id.order_id); - t.truthy(typeof element.order_id.order_id === 'number'); - } - } catch (e) { - console.error(e); - throw e; - } - }, + `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has simple structure`, + async (t) => { + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const { main_table, first_referenced_table, second_referenced_table } = testTablesSimpleKeysData; + + const getMainTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); + t.is(getMainTableRowsResponse.status, 200); + + const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); + t.is(getFirstReferencedTableRowsResponse.status, 200); + + const firstReturnedRows = getFirstReferencedTableRowsRO.rows; + + for (const element of firstReturnedRows) { + t.is(typeof element.customer_id, 'object'); + t.truthy(Object.hasOwn(element.customer_id, 'customer_id')); + t.truthy(element.customer_id.customer_id); + t.truthy(typeof element.customer_id.customer_id === 'number'); + } + + const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); + t.is(getSecondReferencedTableRowsResponse.status, 200); + + const secondReturnedRows = getSecondReferencedTableRowsRO.rows; + for (const element of secondReturnedRows) { + t.is(typeof element.order_id, 'object'); + t.truthy(Object.hasOwn(element.order_id, 'order_id')); + t.truthy(element.order_id.order_id); + t.truthy(typeof element.order_id.order_id === 'number'); + } + } catch (e) { + console.error(e); + throw e; + } + }, ); diff --git a/backend/test/ava-tests/complex-table-tests/complex-mysql-table-e2e.test.ts b/backend/test/ava-tests/complex-table-tests/complex-mysql-table-e2e.test.ts index 221cc9ab3..02d02c846 100644 --- a/backend/test/ava-tests/complex-table-tests/complex-mysql-table-e2e.test.ts +++ b/backend/test/ava-tests/complex-table-tests/complex-mysql-table-e2e.test.ts @@ -17,8 +17,8 @@ import { MockFactory } from '../../mock.factory.js'; import { getTestData } from '../../utils/get-test-data.js'; import { registerUserAndReturnUserInfo } from '../../utils/register-user-and-return-user-info.js'; import { - createTestMySQLTablesWithComplexPFKeys, - createTestMySQLTablesWithSimplePFKeys, + createTestMySQLTablesWithComplexPFKeys, + createTestMySQLTablesWithSimplePFKeys, } from '../../utils/test-utilities/create-test-mysql-tables.js'; import { TestUtils } from '../../utils/test.utils.js'; @@ -35,198 +35,198 @@ let testTablesCompositeKeysData: TableCreationResult; let testTablesSimpleKeysData: TableCreationResult; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication() as any; - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); - - testTablesCompositeKeysData = await createTestMySQLTablesWithComplexPFKeys(connectionToTestDB); - testTablesSimpleKeysData = await createTestMySQLTablesWithSimplePFKeys(connectionToTestDB); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication() as any; + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); + + testTablesCompositeKeysData = await createTestMySQLTablesWithComplexPFKeys(connectionToTestDB); + testTablesSimpleKeysData = await createTestMySQLTablesWithSimplePFKeys(connectionToTestDB); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); export type TableCreationResult = { - main_table: { - table_name: string; - column_names: string[]; - foreign_key_column_names: string[]; - binary_column_names: string[]; - primary_key_column_names: string[]; - }; - first_referenced_table: { - table_name: string; - column_names: string[]; - primary_key_column_names: string[]; - }; - second_referenced_table: { - table_name: string; - column_names: string[]; - primary_key_column_names: string[]; - foreign_key_column_names: string[]; - }; + main_table: { + table_name: string; + column_names: string[]; + foreign_key_column_names: string[]; + binary_column_names: string[]; + primary_key_column_names: string[]; + }; + first_referenced_table: { + table_name: string; + column_names: string[]; + primary_key_column_names: string[]; + }; + second_referenced_table: { + table_name: string; + column_names: string[]; + primary_key_column_names: string[]; + foreign_key_column_names: string[]; + }; }; // GET /connection/tables/:slug test.serial( - `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has composite structure`, - async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const { main_table, first_referenced_table, second_referenced_table } = testTablesCompositeKeysData; - - const getMainTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); - t.is(getMainTableRowsResponse.status, 200); - - const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); - t.is(getFirstReferencedTableRowsResponse.status, 200); - - const firstReturnedRows = getFirstReferencedTableRowsRO.rows; - - for (const row of firstReturnedRows) { - t.is(typeof row.order_id, 'object'); - t.truthy(Object.hasOwn(row.order_id, 'order_id')); - t.truthy(row.order_id.order_id); - t.truthy(typeof row.order_id.order_id === 'number'); - t.is(typeof row.customer_id, 'object'); - t.truthy(Object.hasOwn(row.customer_id, 'customer_id')); - t.truthy(row.customer_id.customer_id); - t.truthy(typeof row.customer_id.customer_id === 'number'); - } - - const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); - t.is(getSecondReferencedTableRowsResponse.status, 200); - const secondReturnedRows = getSecondReferencedTableRowsRO.rows; - for (const row of secondReturnedRows) { - t.is(typeof row.order_id, 'object'); - t.truthy(Object.hasOwn(row.order_id, 'order_id')); - t.truthy(row.order_id.order_id); - t.truthy(typeof row.order_id.order_id === 'number'); - t.is(typeof row.customer_id, 'object'); - t.truthy(Object.hasOwn(row.customer_id, 'customer_id')); - t.truthy(row.customer_id.customer_id); - t.truthy(typeof row.customer_id.customer_id === 'number'); - } - } catch (e) { - console.error(e); - throw e; - } - }, + `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has composite structure`, + async (t) => { + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const { main_table, first_referenced_table, second_referenced_table } = testTablesCompositeKeysData; + + const getMainTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); + t.is(getMainTableRowsResponse.status, 200); + + const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); + t.is(getFirstReferencedTableRowsResponse.status, 200); + + const firstReturnedRows = getFirstReferencedTableRowsRO.rows; + + for (const row of firstReturnedRows) { + t.is(typeof row.order_id, 'object'); + t.truthy(Object.hasOwn(row.order_id, 'order_id')); + t.truthy(row.order_id.order_id); + t.truthy(typeof row.order_id.order_id === 'number'); + t.is(typeof row.customer_id, 'object'); + t.truthy(Object.hasOwn(row.customer_id, 'customer_id')); + t.truthy(row.customer_id.customer_id); + t.truthy(typeof row.customer_id.customer_id === 'number'); + } + + const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); + t.is(getSecondReferencedTableRowsResponse.status, 200); + const secondReturnedRows = getSecondReferencedTableRowsRO.rows; + for (const row of secondReturnedRows) { + t.is(typeof row.order_id, 'object'); + t.truthy(Object.hasOwn(row.order_id, 'order_id')); + t.truthy(row.order_id.order_id); + t.truthy(typeof row.order_id.order_id === 'number'); + t.is(typeof row.customer_id, 'object'); + t.truthy(Object.hasOwn(row.customer_id, 'customer_id')); + t.truthy(row.customer_id.customer_id); + t.truthy(typeof row.customer_id.customer_id === 'number'); + } + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has simple structure`, - async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const { main_table, first_referenced_table, second_referenced_table } = testTablesSimpleKeysData; - - const getMainTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); - t.is(getMainTableRowsResponse.status, 200); - - const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); - t.is(getFirstReferencedTableRowsResponse.status, 200); - - const firstReturnedRows = getFirstReferencedTableRowsRO.rows; - - for (const element of firstReturnedRows) { - t.is(typeof element.customer_id, 'object'); - t.truthy(Object.hasOwn(element.customer_id, 'customer_id')); - t.truthy(element.customer_id.customer_id); - t.truthy(typeof element.customer_id.customer_id === 'number'); - } - - const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); - t.is(getSecondReferencedTableRowsResponse.status, 200); - - const secondReturnedRows = getSecondReferencedTableRowsRO.rows; - for (const element of secondReturnedRows) { - t.is(typeof element.order_id, 'object'); - t.truthy(Object.hasOwn(element.order_id, 'order_id')); - t.truthy(element.order_id.order_id); - t.truthy(typeof element.order_id.order_id === 'number'); - } - } catch (e) { - console.error(e); - throw e; - } - }, + `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has simple structure`, + async (t) => { + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const { main_table, first_referenced_table, second_referenced_table } = testTablesSimpleKeysData; + + const getMainTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); + t.is(getMainTableRowsResponse.status, 200); + + const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); + t.is(getFirstReferencedTableRowsResponse.status, 200); + + const firstReturnedRows = getFirstReferencedTableRowsRO.rows; + + for (const element of firstReturnedRows) { + t.is(typeof element.customer_id, 'object'); + t.truthy(Object.hasOwn(element.customer_id, 'customer_id')); + t.truthy(element.customer_id.customer_id); + t.truthy(typeof element.customer_id.customer_id === 'number'); + } + + const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); + t.is(getSecondReferencedTableRowsResponse.status, 200); + + const secondReturnedRows = getSecondReferencedTableRowsRO.rows; + for (const element of secondReturnedRows) { + t.is(typeof element.order_id, 'object'); + t.truthy(Object.hasOwn(element.order_id, 'order_id')); + t.truthy(element.order_id.order_id); + t.truthy(typeof element.order_id.order_id === 'number'); + } + } catch (e) { + console.error(e); + throw e; + } + }, ); diff --git a/backend/test/ava-tests/complex-table-tests/complex-oracle-table-e2e.test.ts b/backend/test/ava-tests/complex-table-tests/complex-oracle-table-e2e.test.ts index 59b9f89dd..bb3d3cfc0 100644 --- a/backend/test/ava-tests/complex-table-tests/complex-oracle-table-e2e.test.ts +++ b/backend/test/ava-tests/complex-table-tests/complex-oracle-table-e2e.test.ts @@ -17,8 +17,8 @@ import { MockFactory } from '../../mock.factory.js'; import { getTestData } from '../../utils/get-test-data.js'; import { registerUserAndReturnUserInfo } from '../../utils/register-user-and-return-user-info.js'; import { - createTestTablesWithComplexPFKeys, - createTestTablesWithSimplePFKeys, + createTestTablesWithComplexPFKeys, + createTestTablesWithSimplePFKeys, } from '../../utils/test-utilities/create-test-postgres-tables.js'; import { TestUtils } from '../../utils/test.utils.js'; @@ -35,198 +35,198 @@ let testTablesCompositeKeysData: TableCreationResult; let testTablesSimpleKeysData: TableCreationResult; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication() as any; - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); - - testTablesCompositeKeysData = await createTestTablesWithComplexPFKeys(connectionToTestDB); - testTablesSimpleKeysData = await createTestTablesWithSimplePFKeys(connectionToTestDB); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication() as any; + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); + + testTablesCompositeKeysData = await createTestTablesWithComplexPFKeys(connectionToTestDB); + testTablesSimpleKeysData = await createTestTablesWithSimplePFKeys(connectionToTestDB); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); export type TableCreationResult = { - main_table: { - table_name: string; - column_names: string[]; - foreign_key_column_names: string[]; - binary_column_names: string[]; - primary_key_column_names: string[]; - }; - first_referenced_table: { - table_name: string; - column_names: string[]; - primary_key_column_names: string[]; - }; - second_referenced_table: { - table_name: string; - column_names: string[]; - primary_key_column_names: string[]; - foreign_key_column_names: string[]; - }; + main_table: { + table_name: string; + column_names: string[]; + foreign_key_column_names: string[]; + binary_column_names: string[]; + primary_key_column_names: string[]; + }; + first_referenced_table: { + table_name: string; + column_names: string[]; + primary_key_column_names: string[]; + }; + second_referenced_table: { + table_name: string; + column_names: string[]; + primary_key_column_names: string[]; + foreign_key_column_names: string[]; + }; }; // GET /connection/tables/:slug test.serial( - `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has composite structure`, - async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const { main_table, first_referenced_table, second_referenced_table } = testTablesCompositeKeysData; - - const getMainTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); - t.is(getMainTableRowsResponse.status, 200); - - const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); - t.is(getFirstReferencedTableRowsResponse.status, 200); - - const firstReturnedRows = getFirstReferencedTableRowsRO.rows; - - for (const row of firstReturnedRows) { - t.is(typeof row.order_id, 'object'); - t.truthy(Object.hasOwn(row.order_id, 'order_id')); - t.truthy(row.order_id.order_id); - t.truthy(typeof row.order_id.order_id === 'number'); - t.is(typeof row.customer_id, 'object'); - t.truthy(Object.hasOwn(row.customer_id, 'customer_id')); - t.truthy(row.customer_id.customer_id); - t.truthy(typeof row.customer_id.customer_id === 'number'); - } - - const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); - t.is(getSecondReferencedTableRowsResponse.status, 200); - const secondReturnedRows = getSecondReferencedTableRowsRO.rows; - for (const row of secondReturnedRows) { - t.is(typeof row.order_id, 'object'); - t.truthy(Object.hasOwn(row.order_id, 'order_id')); - t.truthy(row.order_id.order_id); - t.truthy(typeof row.order_id.order_id === 'number'); - t.is(typeof row.customer_id, 'object'); - t.truthy(Object.hasOwn(row.customer_id, 'customer_id')); - t.truthy(row.customer_id.customer_id); - t.truthy(typeof row.customer_id.customer_id === 'number'); - } - } catch (e) { - console.error(e); - throw e; - } - }, + `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has composite structure`, + async (t) => { + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const { main_table, first_referenced_table, second_referenced_table } = testTablesCompositeKeysData; + + const getMainTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); + t.is(getMainTableRowsResponse.status, 200); + + const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); + t.is(getFirstReferencedTableRowsResponse.status, 200); + + const firstReturnedRows = getFirstReferencedTableRowsRO.rows; + + for (const row of firstReturnedRows) { + t.is(typeof row.order_id, 'object'); + t.truthy(Object.hasOwn(row.order_id, 'order_id')); + t.truthy(row.order_id.order_id); + t.truthy(typeof row.order_id.order_id === 'number'); + t.is(typeof row.customer_id, 'object'); + t.truthy(Object.hasOwn(row.customer_id, 'customer_id')); + t.truthy(row.customer_id.customer_id); + t.truthy(typeof row.customer_id.customer_id === 'number'); + } + + const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); + t.is(getSecondReferencedTableRowsResponse.status, 200); + const secondReturnedRows = getSecondReferencedTableRowsRO.rows; + for (const row of secondReturnedRows) { + t.is(typeof row.order_id, 'object'); + t.truthy(Object.hasOwn(row.order_id, 'order_id')); + t.truthy(row.order_id.order_id); + t.truthy(typeof row.order_id.order_id === 'number'); + t.is(typeof row.customer_id, 'object'); + t.truthy(Object.hasOwn(row.customer_id, 'customer_id')); + t.truthy(row.customer_id.customer_id); + t.truthy(typeof row.customer_id.customer_id === 'number'); + } + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has simple structure`, - async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const { main_table, first_referenced_table, second_referenced_table } = testTablesSimpleKeysData; - - const getMainTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); - t.is(getMainTableRowsResponse.status, 200); - - const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); - t.is(getFirstReferencedTableRowsResponse.status, 200); - - const firstReturnedRows = getFirstReferencedTableRowsRO.rows; - - for (const element of firstReturnedRows) { - t.is(typeof element.customer_id, 'object'); - t.truthy(Object.hasOwn(element.customer_id, 'customer_id')); - t.truthy(element.customer_id.customer_id); - t.truthy(typeof element.customer_id.customer_id === 'number'); - } - - const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); - t.is(getSecondReferencedTableRowsResponse.status, 200); - - const secondReturnedRows = getSecondReferencedTableRowsRO.rows; - for (const element of secondReturnedRows) { - t.is(typeof element.order_id, 'object'); - t.truthy(Object.hasOwn(element.order_id, 'order_id')); - t.truthy(element.order_id.order_id); - t.truthy(typeof element.order_id.order_id === 'number'); - } - } catch (e) { - console.error(e); - throw e; - } - }, + `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has simple structure`, + async (t) => { + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const { main_table, first_referenced_table, second_referenced_table } = testTablesSimpleKeysData; + + const getMainTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); + t.is(getMainTableRowsResponse.status, 200); + + const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); + t.is(getFirstReferencedTableRowsResponse.status, 200); + + const firstReturnedRows = getFirstReferencedTableRowsRO.rows; + + for (const element of firstReturnedRows) { + t.is(typeof element.customer_id, 'object'); + t.truthy(Object.hasOwn(element.customer_id, 'customer_id')); + t.truthy(element.customer_id.customer_id); + t.truthy(typeof element.customer_id.customer_id === 'number'); + } + + const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); + t.is(getSecondReferencedTableRowsResponse.status, 200); + + const secondReturnedRows = getSecondReferencedTableRowsRO.rows; + for (const element of secondReturnedRows) { + t.is(typeof element.order_id, 'object'); + t.truthy(Object.hasOwn(element.order_id, 'order_id')); + t.truthy(element.order_id.order_id); + t.truthy(typeof element.order_id.order_id === 'number'); + } + } catch (e) { + console.error(e); + throw e; + } + }, ); diff --git a/backend/test/ava-tests/complex-table-tests/complex-postgres-table-e2e.test.ts b/backend/test/ava-tests/complex-table-tests/complex-postgres-table-e2e.test.ts index 3201a35f6..5912432ec 100644 --- a/backend/test/ava-tests/complex-table-tests/complex-postgres-table-e2e.test.ts +++ b/backend/test/ava-tests/complex-table-tests/complex-postgres-table-e2e.test.ts @@ -17,8 +17,8 @@ import { MockFactory } from '../../mock.factory.js'; import { getTestData } from '../../utils/get-test-data.js'; import { registerUserAndReturnUserInfo } from '../../utils/register-user-and-return-user-info.js'; import { - createTestTablesWithComplexPFKeys, - createTestTablesWithSimplePFKeys, + createTestTablesWithComplexPFKeys, + createTestTablesWithSimplePFKeys, } from '../../utils/test-utilities/create-test-postgres-tables.js'; import { TestUtils } from '../../utils/test.utils.js'; @@ -35,198 +35,198 @@ let testTablesCompositeKeysData: TableCreationResult; let testTablesSimpleKeysData: TableCreationResult; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication() as any; - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); - - testTablesCompositeKeysData = await createTestTablesWithComplexPFKeys(connectionToTestDB); - testTablesSimpleKeysData = await createTestTablesWithSimplePFKeys(connectionToTestDB); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication() as any; + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); + + testTablesCompositeKeysData = await createTestTablesWithComplexPFKeys(connectionToTestDB); + testTablesSimpleKeysData = await createTestTablesWithSimplePFKeys(connectionToTestDB); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); export type TableCreationResult = { - main_table: { - table_name: string; - column_names: string[]; - foreign_key_column_names: string[]; - binary_column_names: string[]; - primary_key_column_names: string[]; - }; - first_referenced_table: { - table_name: string; - column_names: string[]; - primary_key_column_names: string[]; - }; - second_referenced_table: { - table_name: string; - column_names: string[]; - primary_key_column_names: string[]; - foreign_key_column_names: string[]; - }; + main_table: { + table_name: string; + column_names: string[]; + foreign_key_column_names: string[]; + binary_column_names: string[]; + primary_key_column_names: string[]; + }; + first_referenced_table: { + table_name: string; + column_names: string[]; + primary_key_column_names: string[]; + }; + second_referenced_table: { + table_name: string; + column_names: string[]; + primary_key_column_names: string[]; + foreign_key_column_names: string[]; + }; }; // GET /connection/tables/:slug test.serial( - `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has composite structure`, - async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const { main_table, first_referenced_table, second_referenced_table } = testTablesCompositeKeysData; - - const getMainTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); - t.is(getMainTableRowsResponse.status, 200); - - const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); - t.is(getFirstReferencedTableRowsResponse.status, 200); - - const firstReturnedRows = getFirstReferencedTableRowsRO.rows; - - for (const row of firstReturnedRows) { - t.is(typeof row.order_id, 'object'); - t.truthy(Object.hasOwn(row.order_id, 'order_id')); - t.truthy(row.order_id.order_id); - t.truthy(typeof row.order_id.order_id === 'number'); - t.is(typeof row.customer_id, 'object'); - t.truthy(Object.hasOwn(row.customer_id, 'customer_id')); - t.truthy(row.customer_id.customer_id); - t.truthy(typeof row.customer_id.customer_id === 'number'); - } - - const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); - t.is(getSecondReferencedTableRowsResponse.status, 200); - const secondReturnedRows = getSecondReferencedTableRowsRO.rows; - for (const row of secondReturnedRows) { - t.is(typeof row.order_id, 'object'); - t.truthy(Object.hasOwn(row.order_id, 'order_id')); - t.truthy(row.order_id.order_id); - t.truthy(typeof row.order_id.order_id === 'number'); - t.is(typeof row.customer_id, 'object'); - t.truthy(Object.hasOwn(row.customer_id, 'customer_id')); - t.truthy(row.customer_id.customer_id); - t.truthy(typeof row.customer_id.customer_id === 'number'); - } - } catch (e) { - console.error(e); - throw e; - } - }, + `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has composite structure`, + async (t) => { + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const { main_table, first_referenced_table, second_referenced_table } = testTablesCompositeKeysData; + + const getMainTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); + t.is(getMainTableRowsResponse.status, 200); + + const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); + t.is(getFirstReferencedTableRowsResponse.status, 200); + + const firstReturnedRows = getFirstReferencedTableRowsRO.rows; + + for (const row of firstReturnedRows) { + t.is(typeof row.order_id, 'object'); + t.truthy(Object.hasOwn(row.order_id, 'order_id')); + t.truthy(row.order_id.order_id); + t.truthy(typeof row.order_id.order_id === 'number'); + t.is(typeof row.customer_id, 'object'); + t.truthy(Object.hasOwn(row.customer_id, 'customer_id')); + t.truthy(row.customer_id.customer_id); + t.truthy(typeof row.customer_id.customer_id === 'number'); + } + + const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); + t.is(getSecondReferencedTableRowsResponse.status, 200); + const secondReturnedRows = getSecondReferencedTableRowsRO.rows; + for (const row of secondReturnedRows) { + t.is(typeof row.order_id, 'object'); + t.truthy(Object.hasOwn(row.order_id, 'order_id')); + t.truthy(row.order_id.order_id); + t.truthy(typeof row.order_id.order_id === 'number'); + t.is(typeof row.customer_id, 'object'); + t.truthy(Object.hasOwn(row.customer_id, 'customer_id')); + t.truthy(row.customer_id.customer_id); + t.truthy(typeof row.customer_id.customer_id === 'number'); + } + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has simple structure`, - async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const { main_table, first_referenced_table, second_referenced_table } = testTablesSimpleKeysData; - - const getMainTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); - t.is(getMainTableRowsResponse.status, 200); - - const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); - t.is(getFirstReferencedTableRowsResponse.status, 200); - - const firstReturnedRows = getFirstReferencedTableRowsRO.rows; - - for (const element of firstReturnedRows) { - t.is(typeof element.customer_id, 'object'); - t.truthy(Object.hasOwn(element.customer_id, 'customer_id')); - t.truthy(element.customer_id.customer_id); - t.truthy(typeof element.customer_id.customer_id === 'number'); - } - - const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); - t.is(getSecondReferencedTableRowsResponse.status, 200); - - const secondReturnedRows = getSecondReferencedTableRowsRO.rows; - for (const element of secondReturnedRows) { - t.is(typeof element.order_id, 'object'); - t.truthy(Object.hasOwn(element.order_id, 'order_id')); - t.truthy(element.order_id.order_id); - t.truthy(typeof element.order_id.order_id === 'number'); - } - } catch (e) { - console.error(e); - throw e; - } - }, + `GET /connection/tables/:slug - Should return list of table rows with referenced columns, when primary and foreign keys has simple structure`, + async (t) => { + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const { main_table, first_referenced_table, second_referenced_table } = testTablesSimpleKeysData; + + const getMainTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${main_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _getMainTableRowsRO = JSON.parse(getMainTableRowsResponse.text); + t.is(getMainTableRowsResponse.status, 200); + + const getFirstReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${first_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getFirstReferencedTableRowsRO = JSON.parse(getFirstReferencedTableRowsResponse.text); + t.is(getFirstReferencedTableRowsResponse.status, 200); + + const firstReturnedRows = getFirstReferencedTableRowsRO.rows; + + for (const element of firstReturnedRows) { + t.is(typeof element.customer_id, 'object'); + t.truthy(Object.hasOwn(element.customer_id, 'customer_id')); + t.truthy(element.customer_id.customer_id); + t.truthy(typeof element.customer_id.customer_id === 'number'); + } + + const getSecondReferencedTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${second_referenced_table.table_name}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getSecondReferencedTableRowsRO = JSON.parse(getSecondReferencedTableRowsResponse.text); + t.is(getSecondReferencedTableRowsResponse.status, 200); + + const secondReturnedRows = getSecondReferencedTableRowsRO.rows; + for (const element of secondReturnedRows) { + t.is(typeof element.order_id, 'object'); + t.truthy(Object.hasOwn(element.order_id, 'order_id')); + t.truthy(element.order_id.order_id); + t.truthy(typeof element.order_id.order_id === 'number'); + } + } catch (e) { + console.error(e); + throw e; + } + }, ); diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-ai-chat-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-ai-chat-e2e.test.ts index 6d3806a2b..58baba120 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-ai-chat-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-ai-chat-e2e.test.ts @@ -12,7 +12,10 @@ import { Cacher } from '../../../src/helpers/cache/cacher.js'; import { DatabaseModule } from '../../../src/shared/database/database.module.js'; import { DatabaseService } from '../../../src/shared/database/database.service.js'; import { MockFactory } from '../../mock.factory.js'; -import { registerUserAndReturnUserInfo, createInitialTestUser } from '../../utils/register-user-and-return-user-info.js'; +import { + registerUserAndReturnUserInfo, + createInitialTestUser, +} from '../../utils/register-user-and-return-user-info.js'; import { setSaasEnvVariable } from '../../utils/set-saas-env-variable.js'; import { TestUtils } from '../../utils/test.utils.js'; import { ValidationException } from '../../../src/exceptions/custom-exceptions/validation-exception.js'; diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-connection-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-connection-e2e.test.ts index db722fd3e..acee6fdf5 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-connection-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-connection-e2e.test.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { faker, } from '@faker-js/faker'; +import { faker } from '@faker-js/faker'; import { INestApplication, ValidationPipe } from '@nestjs/common'; import { Test } from '@nestjs/testing'; import test from 'ava'; @@ -13,9 +13,9 @@ import { DatabaseService } from '../../../src/shared/database/database.service.j import { MockFactory } from '../../mock.factory.js'; import { TestUtils } from '../../utils/test.utils.js'; import { - inviteUserInCompanyAndAcceptInvitation, - registerUserAndReturnUserInfo, - createInitialTestUser, + inviteUserInCompanyAndAcceptInvitation, + registerUserAndReturnUserInfo, + createInitialTestUser, } from '../../utils/register-user-and-return-user-info.js'; import { setSaasEnvVariable } from '../../utils/set-saas-env-variable.js'; import { ValidationException } from '../../../src/exceptions/custom-exceptions/validation-exception.js'; @@ -28,1490 +28,1480 @@ let _testUtils: TestUtils; let currentTest: string; type RegisterUserData = { - email: string; - password: string; + email: string; + password: string; }; test.before(async () => { - setSaasEnvVariable(); - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - _testUtils = moduleFixture.get(TestUtils); - - app = moduleFixture.createNestApplication() as any; - app.use(cookieParser()); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - await createInitialTestUser(app); - app.getHttpServer().listen(0); + setSaasEnvVariable(); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + _testUtils = moduleFixture.get(TestUtils); + + app = moduleFixture.createNestApplication() as any; + app.use(cookieParser()); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + await createInitialTestUser(app); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); function getTestData() { - const newConnection = mockFactory.generateCreateConnectionDto(); - const newConnection2 = mockFactory.generateCreateConnectionDto2(); - const newConnectionToTestDB = mockFactory.generateCreateConnectionDtoToTEstDB(); - const updateConnection = mockFactory.generateUpdateConnectionDto(); - const newGroup1 = mockFactory.generateCreateGroupDto1(); - return { - newConnection, - newConnection2, - newConnectionToTestDB, - updateConnection, - newGroup1, - }; + const newConnection = mockFactory.generateCreateConnectionDto(); + const newConnection2 = mockFactory.generateCreateConnectionDto2(); + const newConnectionToTestDB = mockFactory.generateCreateConnectionDtoToTEstDB(); + const updateConnection = mockFactory.generateUpdateConnectionDto(); + const newGroup1 = mockFactory.generateCreateGroupDto1(); + return { + newConnection, + newConnection2, + newConnectionToTestDB, + updateConnection, + newGroup1, + }; } currentTest = '> GET /connections >'; test.serial(`${currentTest} should return all connections for this user`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - const findAllConnectionsResponse = await request(app.getHttpServer()) - .get('/connections') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(findAllConnectionsResponse.status, 200); - // t.is(findAllConnectionsResponse.body.connections.length, 0); - - let createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createConnectionResult.status, 201); - - createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createConnectionResult.status, 201); - - const findAll = await request(app.getHttpServer()) - .get('/connections') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(findAll.status, 200); - - const result = findAll.body.connections; - - t.is(result.length > 0, true); - t.is(Object.hasOwn(result[0], 'connection'), true); - t.is(Object.hasOwn(result[1], 'accessLevel'), true); - t.is(result[0].accessLevel, AccessLevelEnum.edit); - - t.is(Object.hasOwn(result[1], 'accessLevel'), true); - t.is(Object.hasOwn(result[0].connection, 'host'), true); - t.is(Object.hasOwn(result[1].connection, 'host'), true); - t.is(typeof result[0].connection.port, 'number'); - t.is(Object.hasOwn(result[1].connection, 'username'), true); - t.is(Object.hasOwn(result[0].connection, 'database'), true); - t.is(Object.hasOwn(result[1].connection, 'sid'), true); - t.is(Object.hasOwn(result[0].connection, 'createdAt'), true); - t.is(Object.hasOwn(result[1].connection, 'updatedAt'), true); - t.is(Object.hasOwn(result[0].connection, 'password'), false); - t.is(Object.hasOwn(result[1].connection, 'groups'), false); - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + const findAllConnectionsResponse = await request(app.getHttpServer()) + .get('/connections') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(findAllConnectionsResponse.status, 200); + // t.is(findAllConnectionsResponse.body.connections.length, 0); + + let createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createConnectionResult.status, 201); + + createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createConnectionResult.status, 201); + + const findAll = await request(app.getHttpServer()) + .get('/connections') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(findAll.status, 200); + + const result = findAll.body.connections; + + t.is(result.length > 0, true); + t.is(Object.hasOwn(result[0], 'connection'), true); + t.is(Object.hasOwn(result[1], 'accessLevel'), true); + t.is(result[0].accessLevel, AccessLevelEnum.edit); + + t.is(Object.hasOwn(result[1], 'accessLevel'), true); + t.is(Object.hasOwn(result[0].connection, 'host'), true); + t.is(Object.hasOwn(result[1].connection, 'host'), true); + t.is(typeof result[0].connection.port, 'number'); + t.is(Object.hasOwn(result[1].connection, 'username'), true); + t.is(Object.hasOwn(result[0].connection, 'database'), true); + t.is(Object.hasOwn(result[1].connection, 'sid'), true); + t.is(Object.hasOwn(result[0].connection, 'createdAt'), true); + t.is(Object.hasOwn(result[1].connection, 'updatedAt'), true); + t.is(Object.hasOwn(result[0].connection, 'password'), false); + t.is(Object.hasOwn(result[1].connection, 'groups'), false); + t.pass(); }); currentTest = '> GET connection/users/:slug >'; test.serial(`${currentTest} should return all connection users`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); + t.is(createConnectionResponse.status, 201); - const connectionRO = JSON.parse(createConnectionResponse.text); + const connectionRO = JSON.parse(createConnectionResponse.text); - const findAllUsersResponse = await request(app.getHttpServer()) - .get(`/connection/users/${connectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); + const findAllUsersResponse = await request(app.getHttpServer()) + .get(`/connection/users/${connectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); - t.is(findAllUsersResponse.status, 200); + t.is(findAllUsersResponse.status, 200); - const foundUsersRO = JSON.parse(findAllUsersResponse.text); - t.is(foundUsersRO.length, 1); + const foundUsersRO = JSON.parse(findAllUsersResponse.text); + t.is(foundUsersRO.length, 1); - t.is(foundUsersRO[0].isActive, true); - t.is(Object.hasOwn(foundUsersRO[0], 'createdAt'), true); - t.pass(); + t.is(foundUsersRO[0].isActive, true); + t.is(Object.hasOwn(foundUsersRO[0], 'createdAt'), true); + t.pass(); }); test.serial(`${currentTest} should return all connection users from different groups`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createConnectionResponse.status, 201); - - const connectionRO = JSON.parse(createConnectionResponse.text); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connectionRO.id}`) - .send(newGroup1) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createGroupResponse.status, 201); - const createGroupRO = JSON.parse(createGroupResponse.text); - - const _secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - token, - undefined, - app, - createGroupRO.id, - ); - - // const requestBody = { - // email: secondUserRegisterInfo.email, - // groupId: createGroupRO.id, - // }; - // const addUserInGroupResponse = await request(app.getHttpServer()) - // .put(`/group/user/`) - // .send(requestBody) - // .set('Cookie', token) - // .set('Content-Type', 'application/json') - // .set('Accept', 'application/json'); - - // t.is(addUserInGroupResponse.status, 200); - - const findAllUsersResponse = await request(app.getHttpServer()) - .get(`/connection/users/${connectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(findAllUsersResponse.status, 200); - const foundUsersRO = JSON.parse(findAllUsersResponse.text); - t.is(foundUsersRO.length, 2); - - t.is(foundUsersRO[0].isActive, true); - t.is(foundUsersRO[1].isActive, true); - t.is(Object.hasOwn(foundUsersRO[1], 'email'), true); - t.is(Object.hasOwn(foundUsersRO[0], 'email'), true); - t.is(Object.hasOwn(foundUsersRO[0], 'createdAt'), true); - t.is(Object.hasOwn(foundUsersRO[1], 'createdAt'), true); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createConnectionResponse.status, 201); + + const connectionRO = JSON.parse(createConnectionResponse.text); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connectionRO.id}`) + .send(newGroup1) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createGroupResponse.status, 201); + const createGroupRO = JSON.parse(createGroupResponse.text); + + const _secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation(token, undefined, app, createGroupRO.id); + + // const requestBody = { + // email: secondUserRegisterInfo.email, + // groupId: createGroupRO.id, + // }; + // const addUserInGroupResponse = await request(app.getHttpServer()) + // .put(`/group/user/`) + // .send(requestBody) + // .set('Cookie', token) + // .set('Content-Type', 'application/json') + // .set('Accept', 'application/json'); + + // t.is(addUserInGroupResponse.status, 200); + + const findAllUsersResponse = await request(app.getHttpServer()) + .get(`/connection/users/${connectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(findAllUsersResponse.status, 200); + const foundUsersRO = JSON.parse(findAllUsersResponse.text); + t.is(foundUsersRO.length, 2); + + t.is(foundUsersRO[0].isActive, true); + t.is(foundUsersRO[1].isActive, true); + t.is(Object.hasOwn(foundUsersRO[1], 'email'), true); + t.is(Object.hasOwn(foundUsersRO[0], 'email'), true); + t.is(Object.hasOwn(foundUsersRO[0], 'createdAt'), true); + t.is(Object.hasOwn(foundUsersRO[1], 'createdAt'), true); + + t.pass(); }); test.serial(`${currentTest} should throw an exception, when connection id is incorrect`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createConnectionResponse.status, 201); - const connectionRO = JSON.parse(createConnectionResponse.text); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connectionRO.id}`) - .send(newGroup1) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - const createGroupRO = JSON.parse(createGroupResponse.text); - - const _secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - token, - undefined, - app, - createGroupRO.id, - ); - - // const requestBody = { - // email: secondUserRegisterInfo.email, - // groupId: createGroupRO.id, - // }; - - // const addUserInGroupResponse = await request(app.getHttpServer()) - // .put(`/group/user/`) - // .send(requestBody) - // .set('Content-Type', 'application/json') - // .set('Cookie', token) - // .set('Accept', 'application/json'); - // t.is(addUserInGroupResponse.status, 200); - - const fakeConnectionId = faker.string.uuid(); - const findAllUsersResponse = await request(app.getHttpServer()) - .get(`/connection/users/${fakeConnectionId}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const findAllUsersRO = JSON.parse(findAllUsersResponse.text); - t.is(findAllUsersResponse.status, 403); - t.is(findAllUsersRO.message, Messages.DONT_HAVE_PERMISSIONS); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createConnectionResponse.status, 201); + const connectionRO = JSON.parse(createConnectionResponse.text); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connectionRO.id}`) + .send(newGroup1) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + const createGroupRO = JSON.parse(createGroupResponse.text); + + const _secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation(token, undefined, app, createGroupRO.id); + + // const requestBody = { + // email: secondUserRegisterInfo.email, + // groupId: createGroupRO.id, + // }; + + // const addUserInGroupResponse = await request(app.getHttpServer()) + // .put(`/group/user/`) + // .send(requestBody) + // .set('Content-Type', 'application/json') + // .set('Cookie', token) + // .set('Accept', 'application/json'); + // t.is(addUserInGroupResponse.status, 200); + + const fakeConnectionId = faker.string.uuid(); + const findAllUsersResponse = await request(app.getHttpServer()) + .get(`/connection/users/${fakeConnectionId}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const findAllUsersRO = JSON.parse(findAllUsersResponse.text); + t.is(findAllUsersResponse.status, 403); + t.is(findAllUsersRO.message, Messages.DONT_HAVE_PERMISSIONS); + + t.pass(); }); currentTest = 'GET /connection/one/:slug'; test.serial(`${currentTest} should return a found connection`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - const findOneResponce = await request(app.getHttpServer()) - .get(`/connection/one/${createConnectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(findOneResponce.status, 200); - const result = findOneResponce.body.connection; - - t.is(result.title, 'Test Connection'); - t.is(result.type, 'postgres'); - t.is(result.host, 'nestjs_testing'); - t.is(typeof result.port, 'number'); - t.is(result.port, 5432); - t.is(result.username, 'postgres'); - t.is(result.database, 'nestjs_testing'); - t.is(result.sid, null); - t.is(Object.hasOwn(result, 'createdAt'), true); - t.is(Object.hasOwn(result, 'updatedAt'), true); - t.is(Object.hasOwn(result, 'password'), false); - t.is(Object.hasOwn(result, 'groups'), false); - t.is(Object.hasOwn(result, 'author'), false); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + const findOneResponce = await request(app.getHttpServer()) + .get(`/connection/one/${createConnectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(findOneResponce.status, 200); + const result = findOneResponce.body.connection; + + t.is(result.title, 'Test Connection'); + t.is(result.type, 'postgres'); + t.is(result.host, 'nestjs_testing'); + t.is(typeof result.port, 'number'); + t.is(result.port, 5432); + t.is(result.username, 'postgres'); + t.is(result.database, 'nestjs_testing'); + t.is(result.sid, null); + t.is(Object.hasOwn(result, 'createdAt'), true); + t.is(Object.hasOwn(result, 'updatedAt'), true); + t.is(Object.hasOwn(result, 'password'), false); + t.is(Object.hasOwn(result, 'groups'), false); + t.is(Object.hasOwn(result, 'author'), false); + + t.pass(); }); test.serial( - `${currentTest} should throw an exception "id is missing" when connection id not passed in the request`, - async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - createConnectionRO.id = undefined; - const findOneResponce = await request(app.getHttpServer()) - .get(`/connection/one/${createConnectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(findOneResponce.status, 400); - const { message } = JSON.parse(findOneResponce.text); - t.is(message, Messages.UUID_INVALID); - - t.pass(); - }, + `${currentTest} should throw an exception "id is missing" when connection id not passed in the request`, + async (t) => { + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + createConnectionRO.id = undefined; + const findOneResponce = await request(app.getHttpServer()) + .get(`/connection/one/${createConnectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(findOneResponce.status, 400); + const { message } = JSON.parse(findOneResponce.text); + t.is(message, Messages.UUID_INVALID); + + t.pass(); + }, ); currentTest = 'POST /connection'; test.serial(`${currentTest} should return created connection`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(response.status, 201); - const result = JSON.parse(response.text); - - t.is(result.title, 'Test Connection'); - t.is(result.type, 'postgres'); - t.is(result.host, 'nestjs_testing'); - t.is(typeof result.port, 'number'); - t.is(result.port, 5432); - t.is(result.username, 'postgres'); - t.is(result.database, 'nestjs_testing'); - t.is(result.sid, null); - t.is(Object.hasOwn(result, 'createdAt'), true); - t.is(Object.hasOwn(result, 'updatedAt'), true); - t.is(Object.hasOwn(result, 'password'), false); - t.is(Object.hasOwn(result, 'groups'), true); - t.is(typeof result.groups, 'object'); - t.is(result.groups.length >= 1, true); - - const index = result.groups - .map((e) => { - return e.title; - }) - .indexOf('Admin'); - - t.is(index >= 0, true); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(response.status, 201); + const result = JSON.parse(response.text); + + t.is(result.title, 'Test Connection'); + t.is(result.type, 'postgres'); + t.is(result.host, 'nestjs_testing'); + t.is(typeof result.port, 'number'); + t.is(result.port, 5432); + t.is(result.username, 'postgres'); + t.is(result.database, 'nestjs_testing'); + t.is(result.sid, null); + t.is(Object.hasOwn(result, 'createdAt'), true); + t.is(Object.hasOwn(result, 'updatedAt'), true); + t.is(Object.hasOwn(result, 'password'), false); + t.is(Object.hasOwn(result, 'groups'), true); + t.is(typeof result.groups, 'object'); + t.is(result.groups.length >= 1, true); + + const index = result.groups + .map((e) => { + return e.title; + }) + .indexOf('Admin'); + + t.is(index >= 0, true); + + t.pass(); }); test.serial(`${currentTest} should throw error when create connection without type`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - delete newConnection.type; - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(response.text); - t.is(response.status, 400); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + delete newConnection.type; + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(response.text); + t.is(response.status, 400); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + + t.pass(); }); test.serial(`${currentTest} should throw error when create connection without host`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - delete newConnection.host; - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - t.is(message, Messages.HOST_MISSING); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + delete newConnection.host; + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + t.is(message, Messages.HOST_MISSING); + + t.pass(); }); test.serial(`${currentTest} should throw error when create connection without port`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - delete newConnection.port; - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - t.is(message, `${Messages.PORT_MISSING}, ${Messages.PORT_FORMAT_INCORRECT}`); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + delete newConnection.port; + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + t.is(message, `${Messages.PORT_MISSING}, ${Messages.PORT_FORMAT_INCORRECT}`); + + t.pass(); }); test.serial(`${currentTest} should throw error when create connection wit port value more than 65535`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - newConnection.port = 65536; - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + newConnection.port = 65536; + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + + t.pass(); }); test.serial(`${currentTest} should throw error when create connection wit port value less than 0`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - newConnection.port = -1; - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + newConnection.port = -1; + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + t.pass(); }); test.serial(`${currentTest} should throw error when create connection without username`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - delete newConnection.username; - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - t.is(message, Messages.USERNAME_MISSING); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + delete newConnection.username; + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + t.is(message, Messages.USERNAME_MISSING); + + t.pass(); }); test.serial(`${currentTest} should throw error when create connection without database`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - delete newConnection.database; - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - t.is(message, Messages.DATABASE_MISSING); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + delete newConnection.database; + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + t.is(message, Messages.DATABASE_MISSING); + + t.pass(); }); test.serial(`${currentTest} should throw error when create connection without password`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - delete newConnection.password; - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - t.is(message, Messages.PASSWORD_MISSING); - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + delete newConnection.password; + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + t.is(message, Messages.PASSWORD_MISSING); + t.pass(); }); test.serial( - `${currentTest} should throw error with complex message when create connection without database, type, port`, - async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - delete newConnection.database; - delete newConnection.type; - delete newConnection.port; - - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - - t.pass(); - }, + `${currentTest} should throw error with complex message when create connection without database, type, port`, + async (t) => { + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + delete newConnection.database; + delete newConnection.type; + delete newConnection.port; + + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + + t.pass(); + }, ); currentTest = 'PUT /connection'; test.serial(`${currentTest} should return updated connection`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - const updateConnectionResponse = await request(app.getHttpServer()) - .put(`/connection/${createConnectionRO.id}`) - .send(updateConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(updateConnectionResponse.status, 200); - const result = updateConnectionResponse.body.connection; - - t.is(result.title, 'Updated Test Connection'); - t.is(result.type, 'postgres'); - t.is(result.host, 'testing_nestjs'); - t.is(typeof result.port, 'number'); - t.is(result.port, 5432); - t.is(result.username, 'admin'); - t.is(result.database, 'testing_nestjs'); - t.is(result.sid, null); - t.is(Object.hasOwn(result, 'createdAt'), true); - t.is(Object.hasOwn(result, 'updatedAt'), true); - t.is(Object.hasOwn(result, 'password'), false); - t.is(Object.hasOwn(result, 'groups'), false); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + const updateConnectionResponse = await request(app.getHttpServer()) + .put(`/connection/${createConnectionRO.id}`) + .send(updateConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(updateConnectionResponse.status, 200); + const result = updateConnectionResponse.body.connection; + + t.is(result.title, 'Updated Test Connection'); + t.is(result.type, 'postgres'); + t.is(result.host, 'testing_nestjs'); + t.is(typeof result.port, 'number'); + t.is(result.port, 5432); + t.is(result.username, 'admin'); + t.is(result.database, 'testing_nestjs'); + t.is(result.sid, null); + t.is(Object.hasOwn(result, 'createdAt'), true); + t.is(Object.hasOwn(result, 'updatedAt'), true); + t.is(Object.hasOwn(result, 'password'), false); + t.is(Object.hasOwn(result, 'groups'), false); + + t.pass(); }); test.serial(`${currentTest} 'should throw error when update connection without type'`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - delete updateConnection.type; - - const response = await request(app.getHttpServer()) - .put(`/connection/${createConnectionRO.id}`) - .send(updateConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + delete updateConnection.type; + + const response = await request(app.getHttpServer()) + .put(`/connection/${createConnectionRO.id}`) + .send(updateConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + + t.pass(); }); test.serial(`${currentTest} should throw error when update connection without host`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - delete updateConnection.host; - - const response = await request(app.getHttpServer()) - .put(`/connection/${createConnectionRO.id}`) - .send(updateConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - t.is(message, Messages.HOST_MISSING); - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + delete updateConnection.host; + + const response = await request(app.getHttpServer()) + .put(`/connection/${createConnectionRO.id}`) + .send(updateConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + t.is(message, Messages.HOST_MISSING); + t.pass(); }); test.serial(`${currentTest} should throw error when update connection without port`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - delete updateConnection.port; - - const response = await request(app.getHttpServer()) - .put(`/connection/${createConnectionRO.id}`) - .send(updateConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - t.is(message, `${Messages.PORT_MISSING}, ${Messages.PORT_FORMAT_INCORRECT}`); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + delete updateConnection.port; + + const response = await request(app.getHttpServer()) + .put(`/connection/${createConnectionRO.id}`) + .send(updateConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + t.is(message, `${Messages.PORT_MISSING}, ${Messages.PORT_FORMAT_INCORRECT}`); + + t.pass(); }); test.serial(`${currentTest} should throw error when update connection wit port value more than 65535`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - updateConnection.port = 65536; - - const response = await request(app.getHttpServer()) - .put(`/connection/${createConnectionRO.id}`) - .send(updateConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + updateConnection.port = 65536; + + const response = await request(app.getHttpServer()) + .put(`/connection/${createConnectionRO.id}`) + .send(updateConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + + t.pass(); }); test.serial(`${currentTest} should throw error when update connection wit port value less than 0`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - updateConnection.port = -1; - - const response = await request(app.getHttpServer()) - .put(`/connection/${createConnectionRO.id}`) - .send(updateConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + updateConnection.port = -1; + + const response = await request(app.getHttpServer()) + .put(`/connection/${createConnectionRO.id}`) + .send(updateConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + + t.pass(); }); test.serial(`${currentTest} should throw error when update connection without username`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - delete updateConnection.username; - - const response = await request(app.getHttpServer()) - .put(`/connection/${createConnectionRO.id}`) - .send(updateConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - t.is(message, Messages.USERNAME_MISSING); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + delete updateConnection.username; + + const response = await request(app.getHttpServer()) + .put(`/connection/${createConnectionRO.id}`) + .send(updateConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + t.is(message, Messages.USERNAME_MISSING); + + t.pass(); }); test.serial(`${currentTest} should throw error when update connection without database`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201, createConnectionResponse.text); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - delete updateConnection.database; - - const response = await request(app.getHttpServer()) - .put(`/connection/${createConnectionRO.id}`) - .send(updateConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - t.is(message, Messages.DATABASE_MISSING); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201, createConnectionResponse.text); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + delete updateConnection.database; + + const response = await request(app.getHttpServer()) + .put(`/connection/${createConnectionRO.id}`) + .send(updateConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + t.is(message, Messages.DATABASE_MISSING); + + t.pass(); }); test.serial( - `${currentTest} should throw error with complex message when update connection without database, type, port`, - async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - delete updateConnection.database; - delete updateConnection.type; - delete updateConnection.port; - - const response = await request(app.getHttpServer()) - .put(`/connection/${createConnectionRO.id}`) - .send(updateConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - - t.pass(); - }, + `${currentTest} should throw error with complex message when update connection without database, type, port`, + async (t) => { + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + delete updateConnection.database; + delete updateConnection.type; + delete updateConnection.port; + + const response = await request(app.getHttpServer()) + .put(`/connection/${createConnectionRO.id}`) + .send(updateConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + + t.pass(); + }, ); currentTest = 'DELETE /connection/:slug'; test.serial(`${currentTest} should return delete result`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - - const response = await request(app.getHttpServer()) - .put(`/connection/delete/${createConnectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 200); - const result = response.body; - - //deleted connection not found in database - const findOneResponce = await request(app.getHttpServer()) - .get(`/connection/one/${createConnectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(findOneResponce.status, 400); - - const { message } = JSON.parse(findOneResponce.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - - t.is(Object.hasOwn(result, 'id'), false); - t.is(result.title, 'Test Connection'); - t.is(result.type, 'postgres'); - t.is(result.host, 'nestjs_testing'); - t.is(typeof result.port, 'number'); - t.is(result.port, 5432); - t.is(result.username, 'postgres'); - t.is(result.database, 'nestjs_testing'); - t.is(result.sid, null); - t.is(Object.hasOwn(result, 'createdAt'), true); - t.is(Object.hasOwn(result, 'updatedAt'), true); - t.is(Object.hasOwn(result, 'password'), false); - t.is(Object.hasOwn(result, 'groups'), false); - t.is(Object.hasOwn(result, 'author'), false); - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + + const response = await request(app.getHttpServer()) + .put(`/connection/delete/${createConnectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 200); + const result = response.body; + + //deleted connection not found in database + const findOneResponce = await request(app.getHttpServer()) + .get(`/connection/one/${createConnectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(findOneResponce.status, 400); + + const { message } = JSON.parse(findOneResponce.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + + t.is(Object.hasOwn(result, 'id'), false); + t.is(result.title, 'Test Connection'); + t.is(result.type, 'postgres'); + t.is(result.host, 'nestjs_testing'); + t.is(typeof result.port, 'number'); + t.is(result.port, 5432); + t.is(result.username, 'postgres'); + t.is(result.database, 'nestjs_testing'); + t.is(result.sid, null); + t.is(Object.hasOwn(result, 'createdAt'), true); + t.is(Object.hasOwn(result, 'updatedAt'), true); + t.is(Object.hasOwn(result, 'password'), false); + t.is(Object.hasOwn(result, 'groups'), false); + t.is(Object.hasOwn(result, 'author'), false); + t.pass(); }); test.serial(`${currentTest} should throw an exception when connection not found`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - createConnectionRO.id = faker.string.uuid(); - - const response = await request(app.getHttpServer()) - .put(`/connection/delete/${createConnectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 403); - - const { message } = JSON.parse(response.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + createConnectionRO.id = faker.string.uuid(); + + const response = await request(app.getHttpServer()) + .put(`/connection/delete/${createConnectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 403); + + const { message } = JSON.parse(response.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + t.pass(); }); test.serial(`${currentTest} should throw an exception when connection id not passed in the request`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResult.text); - createConnectionRO.id = ''; + const createConnectionRO = JSON.parse(createConnectionResult.text); + createConnectionRO.id = ''; - const response = await request(app.getHttpServer()) - .delete(`/connection/${createConnectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); + const response = await request(app.getHttpServer()) + .delete(`/connection/${createConnectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); - t.is(response.status, 404); + t.is(response.status, 404); - t.pass(); + t.pass(); }); currentTest = 'POST /connection/group/:slug'; test.serial(`${currentTest} should return a created group`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token, email } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(createGroupResponse.status, 201); - const result = JSON.parse(createGroupResponse.text); - - t.is(result.title, newGroup1.title); - t.is(Object.hasOwn(result, 'users'), true); - t.is(typeof result.users, 'object'); - t.is(result.users.length, 1); - t.is(result.users[0].email, email); - t.is(result.users[0].isActive, true); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token, email } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(createGroupResponse.status, 201); + const result = JSON.parse(createGroupResponse.text); + + t.is(result.title, newGroup1.title); + t.is(Object.hasOwn(result, 'users'), true); + t.is(typeof result.users, 'object'); + t.is(result.users.length, 1); + t.is(result.users[0].email, email); + t.is(result.users[0].isActive, true); + + t.pass(); }); test.serial(`${currentTest} throw an exception when connectionId not passed in request`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - createConnectionRO.id = ''; - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(createGroupResponse.status, 404); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + createConnectionRO.id = ''; + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(createGroupResponse.status, 404); + + t.pass(); }); test.serial(`${currentTest} throw an exception when group title not passed in request`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - delete newGroup1.title; - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const { message } = JSON.parse(createGroupResponse.text); - - t.is(createGroupResponse.status, 400); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + delete newGroup1.title; + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const { message } = JSON.parse(createGroupResponse.text); + + t.is(createGroupResponse.status, 400); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + + t.pass(); }); test.serial(`${currentTest} throw an exception when connectionId is incorrect`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - createConnectionRO.id = faker.string.uuid(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const { message } = JSON.parse(createGroupResponse.text); - - t.is(createGroupResponse.status, 403); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + createConnectionRO.id = faker.string.uuid(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const { message } = JSON.parse(createGroupResponse.text); + + t.is(createGroupResponse.status, 403); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + t.pass(); }); test.serial(`${currentTest} throw an exception when group name is not unique`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .set('Cookie', token) - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - newGroup1.title = 'Admin'; - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(createGroupResponse.text); - - t.is(createGroupResponse.status, 400); - t.is(message, Messages.GROUP_NAME_UNIQUE); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .set('Cookie', token) + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + newGroup1.title = 'Admin'; + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(createGroupResponse.text); + + t.is(createGroupResponse.status, 400); + t.is(message, Messages.GROUP_NAME_UNIQUE); + + t.pass(); }); currentTest = 'PUT /connection/group/delete/:slug'; test.serial(`${currentTest} should return connection without deleted group result`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - // create group in connection - let result = createGroupResponse.body; - - t.is(createGroupResponse.status, 201); - - t.is(Object.hasOwn(result, 'id'), true); - t.is(result.title, newGroup1.title); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - let response = await request(app.getHttpServer()) - .put(`/connection/group/delete/${createConnectionRO.id}`) - .send({ groupId: createGroupRO.id }) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - //after deleting group - result = response.body; - - t.is(response.status, 200); - t.is(Object.hasOwn(result, 'title'), true); - t.is(result.title, createGroupRO.title); - t.is(result.isMain, false); - // check that group was deleted - - response = await request(app.getHttpServer()) - .get(`/connection/groups/${createConnectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 200); - result = JSON.parse(response.text); - t.is(result.length, 1); - const _groupId = result[0].group.id; - - t.is(Object.hasOwn(result[0].group, 'title'), true); - t.is(result[0].accessLevel, AccessLevelEnum.edit); - - const index = result - .map((e) => { - return e.group.title; - }) - .indexOf('Admin'); - - t.is(index >= 0, true); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + // create group in connection + let result = createGroupResponse.body; + + t.is(createGroupResponse.status, 201); + + t.is(Object.hasOwn(result, 'id'), true); + t.is(result.title, newGroup1.title); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + let response = await request(app.getHttpServer()) + .put(`/connection/group/delete/${createConnectionRO.id}`) + .send({ groupId: createGroupRO.id }) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + //after deleting group + result = response.body; + + t.is(response.status, 200); + t.is(Object.hasOwn(result, 'title'), true); + t.is(result.title, createGroupRO.title); + t.is(result.isMain, false); + // check that group was deleted + + response = await request(app.getHttpServer()) + .get(`/connection/groups/${createConnectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 200); + result = JSON.parse(response.text); + t.is(result.length, 1); + const _groupId = result[0].group.id; + + t.is(Object.hasOwn(result[0].group, 'title'), true); + t.is(result[0].accessLevel, AccessLevelEnum.edit); + + const index = result + .map((e) => { + return e.group.title; + }) + .indexOf('Admin'); + + t.is(index >= 0, true); + + t.pass(); }); test.serial(`${currentTest}`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + t.pass(); }); test.serial(`${currentTest} should throw an exception when connection id is not passed in the request`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - // create group in connection - const result = createGroupResponse.body; - - t.is(createGroupResponse.status, 201); - - t.is(Object.hasOwn(result, 'id'), true); - t.is(result.title, newGroup1.title); - - const createGroupRO = JSON.parse(createGroupResponse.text); - createConnectionRO.id = ''; - const response = await request(app.getHttpServer()) - .put(`/connection/group/delete/${createConnectionRO.id}`) - .send({ groupId: createGroupRO.id }) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(response.status, 404); - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + // create group in connection + const result = createGroupResponse.body; + + t.is(createGroupResponse.status, 201); + + t.is(Object.hasOwn(result, 'id'), true); + t.is(result.title, newGroup1.title); + + const createGroupRO = JSON.parse(createGroupResponse.text); + createConnectionRO.id = ''; + const response = await request(app.getHttpServer()) + .put(`/connection/group/delete/${createConnectionRO.id}`) + .send({ groupId: createGroupRO.id }) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(response.status, 404); + t.pass(); }); test.serial(`${currentTest} should throw an exception when group id is not passed in the request`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - // create group in connection - const result = createGroupResponse.body; - - t.is(createGroupResponse.status, 201); - - t.is(Object.hasOwn(result, 'id'), true); - t.is(result.title, newGroup1.title); - - const createGroupRO = JSON.parse(createGroupResponse.text); - delete createGroupRO.id; - const response = await request(app.getHttpServer()) - .put(`/connection/group/delete/${createConnectionRO.id}`) - .send({ groupId: createGroupRO.id }) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(response.text); - t.is(response.status, 400); - t.is(message, Messages.PARAMETER_NAME_MISSING('groupId')); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + // create group in connection + const result = createGroupResponse.body; + + t.is(createGroupResponse.status, 201); + + t.is(Object.hasOwn(result, 'id'), true); + t.is(result.title, newGroup1.title); + + const createGroupRO = JSON.parse(createGroupResponse.text); + delete createGroupRO.id; + const response = await request(app.getHttpServer()) + .put(`/connection/group/delete/${createConnectionRO.id}`) + .send({ groupId: createGroupRO.id }) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(response.text); + t.is(response.status, 400); + t.is(message, Messages.PARAMETER_NAME_MISSING('groupId')); + + t.pass(); }); test.serial(`${currentTest} should throw an exception when group id is incorrect`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - // create group in connection - const result = createGroupResponse.body; - - t.is(createGroupResponse.status, 201); - - t.is(Object.hasOwn(result, 'id'), true); - t.is(result.title, newGroup1.title); - - const createGroupRO = JSON.parse(createGroupResponse.text); - createGroupRO.id = faker.string.uuid(); - const response = await request(app.getHttpServer()) - .put(`/connection/group/delete/${createConnectionRO.id}`) - .send({ groupId: createGroupRO.id }) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(response.text); - t.is(response.status, 400); - t.is(message, Messages.GROUP_NOT_FOUND); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + // create group in connection + const result = createGroupResponse.body; + + t.is(createGroupResponse.status, 201); + + t.is(Object.hasOwn(result, 'id'), true); + t.is(result.title, newGroup1.title); + + const createGroupRO = JSON.parse(createGroupResponse.text); + createGroupRO.id = faker.string.uuid(); + const response = await request(app.getHttpServer()) + .put(`/connection/group/delete/${createConnectionRO.id}`) + .send({ groupId: createGroupRO.id }) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(response.text); + t.is(response.status, 400); + t.is(message, Messages.GROUP_NOT_FOUND); + + t.pass(); }); test.serial(`${currentTest} should throw an exception when connection id is incorrect`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - // create group in connection - const result = createGroupResponse.body; - - t.is(createGroupResponse.status, 201); - - t.is(Object.hasOwn(result, 'id'), true); - t.is(result.title, newGroup1.title); - - const createGroupRO = JSON.parse(createGroupResponse.text); - createConnectionRO.id = faker.string.uuid(); - const response = await request(app.getHttpServer()) - .put(`/connection/group/delete/${createConnectionRO.id}`) - .send({ groupId: createGroupRO.id }) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const { message } = JSON.parse(response.text); - t.is(response.status, 403); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + // create group in connection + const result = createGroupResponse.body; + + t.is(createGroupResponse.status, 201); + + t.is(Object.hasOwn(result, 'id'), true); + t.is(result.title, newGroup1.title); + + const createGroupRO = JSON.parse(createGroupResponse.text); + createConnectionRO.id = faker.string.uuid(); + const response = await request(app.getHttpServer()) + .put(`/connection/group/delete/${createConnectionRO.id}`) + .send({ groupId: createGroupRO.id }) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const { message } = JSON.parse(response.text); + t.is(response.status, 403); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + t.pass(); }); test.serial(`${currentTest} should throw an exception when trying delete admin group`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - - const response = await request(app.getHttpServer()) - .put(`/connection/group/delete/${createConnectionRO.id}`) - .send({ groupId: createConnectionRO.groups[0].id }) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const { message } = JSON.parse(response.text); - t.is(response.status, 403); - t.is(message, Messages.CANT_DELETE_ADMIN_GROUP); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + + const response = await request(app.getHttpServer()) + .put(`/connection/group/delete/${createConnectionRO.id}`) + .send({ groupId: createConnectionRO.groups[0].id }) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const { message } = JSON.parse(response.text); + t.is(response.status, 403); + t.is(message, Messages.CANT_DELETE_ADMIN_GROUP); + + t.pass(); }); currentTest = 'PUT /connection/encryption/restore/:slug'; test.serial(`${currentTest} should return restored connection`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const newPgConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); - newPgConnection.masterEncryption = true; - - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newPgConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResult.status, 201); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - const { id, groups } = createConnectionRO; - const groupId = groups[0].id; - const restoreConnectionResult = await request(app.getHttpServer()) - .put(`/connection/encryption/restore/${id}`) - .send(newPgConnection) - .set('masterpwd', 'hamalaiahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(restoreConnectionResult.status, 200); - const restoreConnectionResultRO = JSON.parse(restoreConnectionResult.text); - const { connection } = restoreConnectionResultRO; - t.is(connection.id, id); - - const response = await request(app.getHttpServer()) - .get(`/connection/groups/${id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const result = JSON.parse(response.text); - t.is(response.status, 200); - const groupIdInRestoredConnection = result[0].group.id; - t.is(groupIdInRestoredConnection, groupId); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const newPgConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); + newPgConnection.masterEncryption = true; + + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newPgConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResult.status, 201); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + const { id, groups } = createConnectionRO; + const groupId = groups[0].id; + const restoreConnectionResult = await request(app.getHttpServer()) + .put(`/connection/encryption/restore/${id}`) + .send(newPgConnection) + .set('masterpwd', 'hamalaiahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(restoreConnectionResult.status, 200); + const restoreConnectionResultRO = JSON.parse(restoreConnectionResult.text); + const { connection } = restoreConnectionResultRO; + t.is(connection.id, id); + + const response = await request(app.getHttpServer()) + .get(`/connection/groups/${id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const result = JSON.parse(response.text); + t.is(response.status, 200); + const groupIdInRestoredConnection = result[0].group.id; + t.is(groupIdInRestoredConnection, groupId); + + t.pass(); }); currentTest = 'GET /connection/groups/:slug'; test.serial(`${currentTest} should groups in connection`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(createGroupResponse.status, 201); - - const response = await request(app.getHttpServer()) - .get(`/connection/groups/${createConnectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 200); - const result = JSON.parse(response.text); - const _groupId = result[0].group.id; - - t.is(Object.hasOwn(result[1].group, 'title'), true); - t.is(result[0].accessLevel, AccessLevelEnum.edit); - - const index = result - .map((e) => { - return e.group.title; - }) - .indexOf('Admin'); - - t.is(index >= 0, true); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(createGroupResponse.status, 201); + + const response = await request(app.getHttpServer()) + .get(`/connection/groups/${createConnectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 200); + const result = JSON.parse(response.text); + const _groupId = result[0].group.id; + + t.is(Object.hasOwn(result[1].group, 'title'), true); + t.is(result[0].accessLevel, AccessLevelEnum.edit); + + const index = result + .map((e) => { + return e.group.title; + }) + .indexOf('Admin'); + + t.is(index >= 0, true); + + t.pass(); }); test.serial(`${currentTest} should throw an exception when connection id not passed in the request`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(createGroupResponse.status, 201); - - createConnectionRO.id = ''; - const response = await request(app.getHttpServer()) - .get(`/connection/groups/${createConnectionRO.id}`) - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 404); - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(createGroupResponse.status, 201); + + createConnectionRO.id = ''; + const response = await request(app.getHttpServer()) + .get(`/connection/groups/${createConnectionRO.id}`) + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 404); + t.pass(); }); test.serial(`${currentTest} should throw an exception when connection id is invalid`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(createGroupResponse.status, 201); - createConnectionRO.id = faker.string.uuid(); - const response = await request(app.getHttpServer()) - .get(`/connection/groups/${createConnectionRO.id}`) - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(response.status, 200); - const getGroupsRO = JSON.parse(response.text); - t.is(Array.isArray(getGroupsRO), true); - t.is(getGroupsRO.length, 0); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(createGroupResponse.status, 201); + createConnectionRO.id = faker.string.uuid(); + const response = await request(app.getHttpServer()) + .get(`/connection/groups/${createConnectionRO.id}`) + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(response.status, 200); + const getGroupsRO = JSON.parse(response.text); + t.is(Array.isArray(getGroupsRO), true); + t.is(getGroupsRO.length, 0); + + t.pass(); }); //todo realise diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-connection-properties-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-connection-properties-e2e.test.ts index c7acb830a..3fe0f53fd 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-connection-properties-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-connection-properties-e2e.test.ts @@ -11,7 +11,10 @@ import { DatabaseService } from '../../../src/shared/database/database.service.j import { MockFactory } from '../../mock.factory.js'; import { getTestKnex } from '../../utils/get-test-knex.js'; import { TestUtils } from '../../utils/test.utils.js'; -import { registerUserAndReturnUserInfo, createInitialTestUser } from '../../utils/register-user-and-return-user-info.js'; +import { + registerUserAndReturnUserInfo, + createInitialTestUser, +} from '../../utils/register-user-and-return-user-info.js'; import { setSaasEnvVariable } from '../../utils/set-saas-env-variable.js'; import { ValidationException } from '../../../src/exceptions/custom-exceptions/validation-exception.js'; import { ValidationError } from 'class-validator'; @@ -31,69 +34,69 @@ const testTables: Array = []; let currentTest; test.before(async () => { - setSaasEnvVariable(); - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - _testUtils = moduleFixture.get(TestUtils); - - app = moduleFixture.createNestApplication(); - app.use(cookieParser()); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - await createInitialTestUser(app); - app.getHttpServer().listen(0); + setSaasEnvVariable(); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + _testUtils = moduleFixture.get(TestUtils); + + app = moduleFixture.createNestApplication(); + app.use(cookieParser()); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + await createInitialTestUser(app); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); async function resetPostgresTestDB(testTableName) { - const Knex = getTestKnex(mockFactory.generateConnectionToTestPostgresDBInDocker()); - await Knex.schema.createTableIfNotExists(testTableName, (table) => { - table.increments(); - table.string(testTableColumnName); - table.string(testTAbleSecondColumnName); - table.timestamps(); - }); - - for (let i = 0; i < testEntitiesSeedsCount; i++) { - if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { - await Knex(testTableName).insert({ - [testTableColumnName]: testSearchedUserName, - [testTAbleSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - }); - } else { - await Knex(testTableName).insert({ - [testTableColumnName]: faker.person.firstName(), - [testTAbleSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - }); - } - } + const Knex = getTestKnex(mockFactory.generateConnectionToTestPostgresDBInDocker()); + await Knex.schema.createTableIfNotExists(testTableName, (table) => { + table.increments(); + table.string(testTableColumnName); + table.string(testTAbleSecondColumnName); + table.timestamps(); + }); + + for (let i = 0; i < testEntitiesSeedsCount; i++) { + if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { + await Knex(testTableName).insert({ + [testTableColumnName]: testSearchedUserName, + [testTAbleSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + }); + } else { + await Knex(testTableName).insert({ + [testTableColumnName]: faker.person.firstName(), + [testTAbleSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + }); + } + } } test.beforeEach(async (_t) => { - testTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - testTables.push(testTableName); - newConnectionProperties = mockFactory.generateConnectionPropertiesUserExcluded(testTableName); - await resetPostgresTestDB(testTableName); + testTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + testTables.push(testTableName); + newConnectionProperties = mockFactory.generateConnectionPropertiesUserExcluded(testTableName); + await resetPostgresTestDB(testTableName); }); // test.after('cleanup', async (t) => { @@ -101,286 +104,286 @@ test.beforeEach(async (_t) => { // }); type RegisterUserData = { - email: string; - password: string; + email: string; + password: string; }; function getTestData() { - const newConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); - const newConnection2 = mockFactory.generateCreateConnectionDto2(); - const newConnectionToTestDB = mockFactory.generateCreateConnectionDtoToTEstDB(); - const updateConnection = mockFactory.generateUpdateConnectionDto(); - const newGroup1 = mockFactory.generateCreateGroupDto1(); - return { - newConnection, - newConnection2, - newConnectionToTestDB, - updateConnection, - newGroup1, - }; + const newConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); + const newConnection2 = mockFactory.generateCreateConnectionDto2(); + const newConnectionToTestDB = mockFactory.generateCreateConnectionDtoToTEstDB(); + const updateConnection = mockFactory.generateUpdateConnectionDto(); + const newGroup1 = mockFactory.generateCreateGroupDto1(); + return { + newConnection, + newConnection2, + newConnectionToTestDB, + updateConnection, + newGroup1, + }; } currentTest = 'POST /connection/properties/:slug'; test.serial(`${currentTest} should return created connection properties`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${createConnectionRO.id}`) - .send(newConnectionProperties) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); - t.is(createConnectionPropertiesResponse.status, 201); - t.is(createConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); - t.is(createConnectionPropertiesRO.connectionId, createConnectionRO.id); - t.is(createConnectionPropertiesRO.logo_url, newConnectionProperties.logo_url); - t.is(createConnectionPropertiesRO.primary_color, newConnectionProperties.primary_color); - t.is(createConnectionPropertiesRO.secondary_color, newConnectionProperties.secondary_color); - t.is(createConnectionPropertiesRO.hostname, newConnectionProperties.hostname); - t.is(createConnectionPropertiesRO.human_readable_table_names, newConnectionProperties.human_readable_table_names); - t.is(createConnectionPropertiesRO.tables_audit, newConnectionProperties.tables_audit); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(newConnectionProperties) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); + t.is(createConnectionPropertiesResponse.status, 201); + t.is(createConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); + t.is(createConnectionPropertiesRO.connectionId, createConnectionRO.id); + t.is(createConnectionPropertiesRO.logo_url, newConnectionProperties.logo_url); + t.is(createConnectionPropertiesRO.primary_color, newConnectionProperties.primary_color); + t.is(createConnectionPropertiesRO.secondary_color, newConnectionProperties.secondary_color); + t.is(createConnectionPropertiesRO.hostname, newConnectionProperties.hostname); + t.is(createConnectionPropertiesRO.human_readable_table_names, newConnectionProperties.human_readable_table_names); + t.is(createConnectionPropertiesRO.tables_audit, newConnectionProperties.tables_audit); }); test.serial(`${currentTest} should return connection without excluded tables`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${createConnectionRO.id}`) - .send(newConnectionProperties) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); - t.is(createConnectionPropertiesResponse.status, 201); - t.is(createConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); - t.is(createConnectionPropertiesRO.connectionId, createConnectionRO.id); - - const getConnectionTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const getConnectionTablesRO = JSON.parse(getConnectionTablesResponse.text); - t.is(getConnectionTablesRO.length > 0, true); - const hiddenTable = getConnectionTablesRO.find((table) => table.name === newConnectionProperties.hidden_tables[0]); - t.is(hiddenTable, undefined); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(newConnectionProperties) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); + t.is(createConnectionPropertiesResponse.status, 201); + t.is(createConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); + t.is(createConnectionPropertiesRO.connectionId, createConnectionRO.id); + + const getConnectionTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getConnectionTablesRO = JSON.parse(getConnectionTablesResponse.text); + t.is(getConnectionTablesRO.length > 0, true); + const hiddenTable = getConnectionTablesRO.find((table) => table.name === newConnectionProperties.hidden_tables[0]); + t.is(hiddenTable, undefined); }); test.serial(`${currentTest} should throw an exception when excluded table name is incorrect`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const copyNewConnectionResponse = JSON.parse(JSON.stringify(newConnectionProperties)); - copyNewConnectionResponse.hidden_tables[0] = `${faker.lorem.words(1)}_${faker.number.int({ - min: 1, - max: 10000, - })}`; - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${createConnectionRO.id}`) - .send(copyNewConnectionResponse) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const _createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); - t.is(createConnectionPropertiesResponse.status, 400); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const copyNewConnectionResponse = JSON.parse(JSON.stringify(newConnectionProperties)); + copyNewConnectionResponse.hidden_tables[0] = `${faker.lorem.words(1)}_${faker.number.int({ + min: 1, + max: 10000, + })}`; + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(copyNewConnectionResponse) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const _createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); + t.is(createConnectionPropertiesResponse.status, 400); }); currentTest = 'GET /connection/properties/:slug'; test.serial(`${currentTest} should return connection properties`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${createConnectionRO.id}`) - .send(newConnectionProperties) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionPropertiesResponse.status, 201); - - const getConnectionPropertiesResponse = await request(app.getHttpServer()) - .get(`/connection/properties/${createConnectionRO.id}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getConnectionPropertiesRO = JSON.parse(getConnectionPropertiesResponse.text); - t.is(getConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); - t.is(getConnectionPropertiesRO.connectionId, createConnectionRO.id); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(newConnectionProperties) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionPropertiesResponse.status, 201); + + const getConnectionPropertiesResponse = await request(app.getHttpServer()) + .get(`/connection/properties/${createConnectionRO.id}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getConnectionPropertiesRO = JSON.parse(getConnectionPropertiesResponse.text); + t.is(getConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); + t.is(getConnectionPropertiesRO.connectionId, createConnectionRO.id); }); test.serial(`${currentTest} should throw exception when connection id is incorrect`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${createConnectionRO.id}`) - .send(newConnectionProperties) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionPropertiesResponse.status, 201); - - const getConnectionPropertiesResponse = await request(app.getHttpServer()) - .get(`/connection/properties/${faker.string.uuid()}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getConnectionPropertiesResponse.status, 403); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(newConnectionProperties) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionPropertiesResponse.status, 201); + + const getConnectionPropertiesResponse = await request(app.getHttpServer()) + .get(`/connection/properties/${faker.string.uuid()}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getConnectionPropertiesResponse.status, 403); }); currentTest = 'DELETE /connection/properties/:slug'; test.serial(`${currentTest} should return deleted connection properties`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${createConnectionRO.id}`) - .send(newConnectionProperties) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionPropertiesResponse.status, 201); - - const getConnectionPropertiesResponse = await request(app.getHttpServer()) - .get(`/connection/properties/${createConnectionRO.id}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionPropertiesResponse.status, 201); - - const getConnectionPropertiesRO = JSON.parse(getConnectionPropertiesResponse.text); - t.is(getConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); - t.is(getConnectionPropertiesRO.connectionId, createConnectionRO.id); - - const deleteConnectionPropertiesResponse = await request(app.getHttpServer()) - .delete(`/connection/properties/${createConnectionRO.id}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(deleteConnectionPropertiesResponse.status, 200); - const deleteConnectionPropertiesRO = JSON.parse(deleteConnectionPropertiesResponse.text); - - t.is(deleteConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); - - const getConnectionPropertiesResponseAfterDeletion = await request(app.getHttpServer()) - .get(`/connection/properties/${createConnectionRO.id}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionPropertiesResponse.status, 201); - const _getConnectionPropertiesAfterDeletionRO = getConnectionPropertiesResponseAfterDeletion.text; + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(newConnectionProperties) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionPropertiesResponse.status, 201); + + const getConnectionPropertiesResponse = await request(app.getHttpServer()) + .get(`/connection/properties/${createConnectionRO.id}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionPropertiesResponse.status, 201); + + const getConnectionPropertiesRO = JSON.parse(getConnectionPropertiesResponse.text); + t.is(getConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); + t.is(getConnectionPropertiesRO.connectionId, createConnectionRO.id); + + const deleteConnectionPropertiesResponse = await request(app.getHttpServer()) + .delete(`/connection/properties/${createConnectionRO.id}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(deleteConnectionPropertiesResponse.status, 200); + const deleteConnectionPropertiesRO = JSON.parse(deleteConnectionPropertiesResponse.text); + + t.is(deleteConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); + + const getConnectionPropertiesResponseAfterDeletion = await request(app.getHttpServer()) + .get(`/connection/properties/${createConnectionRO.id}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionPropertiesResponse.status, 201); + const _getConnectionPropertiesAfterDeletionRO = getConnectionPropertiesResponseAfterDeletion.text; }); test.serial(`${currentTest} should throw exception when connection id is incorrect`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${createConnectionRO.id}`) - .send(newConnectionProperties) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionPropertiesResponse.status, 201); - - const getConnectionPropertiesResponse = await request(app.getHttpServer()) - .get(`/connection/properties/${faker.string.uuid()}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getConnectionPropertiesResponse.status, 403); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(newConnectionProperties) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionPropertiesResponse.status, 201); + + const getConnectionPropertiesResponse = await request(app.getHttpServer()) + .get(`/connection/properties/${faker.string.uuid()}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getConnectionPropertiesResponse.status, 403); }); currentTest = 'PUT /connection/properties/:slug'; test.serial(`${currentTest} should return updated connection properties`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${createConnectionRO.id}`) - .send(newConnectionProperties) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); - t.is(createConnectionPropertiesResponse.status, 201); - t.is(createConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); - t.is(createConnectionPropertiesRO.connectionId, createConnectionRO.id); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(newConnectionProperties) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); + t.is(createConnectionPropertiesResponse.status, 201); + t.is(createConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); + t.is(createConnectionPropertiesRO.connectionId, createConnectionRO.id); }); // test.serial(`${currentTest} `, async (t) => { diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-custom-field-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-custom-field-e2e.test.ts index cc4b4e70d..ad398d849 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-custom-field-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-custom-field-e2e.test.ts @@ -9,7 +9,10 @@ import { INestApplication, ValidationPipe } from '@nestjs/common'; import { MockFactory } from '../../mock.factory.js'; import { Encryptor } from '../../../src/helpers/encryption/encryptor.js'; import test from 'ava'; -import { registerUserAndReturnUserInfo, createInitialTestUser } from '../../utils/register-user-and-return-user-info.js'; +import { + registerUserAndReturnUserInfo, + createInitialTestUser, +} from '../../utils/register-user-and-return-user-info.js'; import { getTestData } from '../../utils/get-test-data.js'; import request from 'supertest'; import { replaceTextInCurlies } from '../../../src/helpers/index.js'; diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-dashboard-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-dashboard-e2e.test.ts index fa046ff5a..949f40d17 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-dashboard-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-dashboard-e2e.test.ts @@ -15,7 +15,10 @@ import { DatabaseModule } from '../../../src/shared/database/database.module.js' import { DatabaseService } from '../../../src/shared/database/database.service.js'; import { MockFactory } from '../../mock.factory.js'; import { getTestData } from '../../utils/get-test-data.js'; -import { registerUserAndReturnUserInfo, createInitialTestUser } from '../../utils/register-user-and-return-user-info.js'; +import { + registerUserAndReturnUserInfo, + createInitialTestUser, +} from '../../utils/register-user-and-return-user-info.js'; import { setSaasEnvVariable } from '../../utils/set-saas-env-variable.js'; import { TestUtils } from '../../utils/test.utils.js'; import { DashboardWidgetTypeEnum } from '../../../src/enums/dashboard-widget-type.enum.js'; diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-group-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-group-e2e.test.ts index 4ab8a4c9b..ba601815b 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-group-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-group-e2e.test.ts @@ -10,9 +10,9 @@ import { DatabaseService } from '../../../src/shared/database/database.service.j import cookieParser from 'cookie-parser'; import { AllExceptionsFilter } from '../../../src/exceptions/all-exceptions.filter.js'; import { - inviteUserInCompanyAndAcceptInvitation, - registerUserAndReturnUserInfo, - createInitialTestUser, + inviteUserInCompanyAndAcceptInvitation, + registerUserAndReturnUserInfo, + createInitialTestUser, } from '../../utils/register-user-and-return-user-info.js'; import { getTestData } from '../../utils/get-test-data.js'; import request from 'supertest'; @@ -31,1212 +31,1212 @@ let _testUtils: TestUtils; const mockFactory = new MockFactory(); test.before(async () => { - setSaasEnvVariable(); - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - await createInitialTestUser(app); - app.getHttpServer().listen(0); + setSaasEnvVariable(); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + await createInitialTestUser(app); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); let currentTest = 'GET /groups'; test.serial(`${currentTest} should return all user groups`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const findAllUserGroups = await request(app.getHttpServer()) - .get(`/connection/groups/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(findAllUserGroups.status, 200); - - const result = JSON.parse(findAllUserGroups.text); - - t.is(result.length, 2); - - t.is(Object.hasOwn(result[1].group, 'users'), true); - t.is(Object.hasOwn(result[0].group, 'title'), true); - t.is(Object.hasOwn(result[0].group, 'connection'), false); - t.is(result[1].accessLevel, AccessLevelEnum.edit); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const findAllUserGroups = await request(app.getHttpServer()) + .get(`/connection/groups/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(findAllUserGroups.status, 200); + + const result = JSON.parse(findAllUserGroups.text); + + t.is(result.length, 2); + + t.is(Object.hasOwn(result[1].group, 'users'), true); + t.is(Object.hasOwn(result[0].group, 'title'), true); + t.is(Object.hasOwn(result[0].group, 'connection'), false); + t.is(result[1].accessLevel, AccessLevelEnum.edit); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'GET /group/users/:slug'; test.serial(`${currentTest} should return all users in current group`, async (t) => { - try { - const registeredUserInfo = await registerUserAndReturnUserInfo(app); - const firstUserToken = registeredUserInfo.token; - const firstUserEmail = registeredUserInfo.email; - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - const findAllUsersInGroup = await request(app.getHttpServer()) - .get(`/group/users/${createGroupRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(findAllUsersInGroup.status, 200); - const result = JSON.parse(findAllUsersInGroup.text); - t.is(result.length === 1, true); - - // t.is(result[0].isActive).toBe(true); - t.is(result[0].email, firstUserEmail); - } catch (e) { - console.error(e); - throw e; - } + try { + const registeredUserInfo = await registerUserAndReturnUserInfo(app); + const firstUserToken = registeredUserInfo.token; + const firstUserEmail = registeredUserInfo.email; + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + const findAllUsersInGroup = await request(app.getHttpServer()) + .get(`/group/users/${createGroupRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(findAllUsersInGroup.status, 200); + const result = JSON.parse(findAllUsersInGroup.text); + t.is(result.length === 1, true); + + // t.is(result[0].isActive).toBe(true); + t.is(result[0].email, firstUserEmail); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when group id is not real`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - createGroupRO.id = faker.string.uuid(); - const findAllUsersInGroup = await request(app.getHttpServer()) - .get(`/group/users/${createGroupRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(findAllUsersInGroup.status, 400); - const { message } = JSON.parse(findAllUsersInGroup.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + createGroupRO.id = faker.string.uuid(); + const findAllUsersInGroup = await request(app.getHttpServer()) + .get(`/group/users/${createGroupRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(findAllUsersInGroup.status, 400); + const { message } = JSON.parse(findAllUsersInGroup.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when group id not passed`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - createGroupRO.id = ''; - const findAllUsersInGroup = await request(app.getHttpServer()) - .get(`/group/users/${createGroupRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(findAllUsersInGroup.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + createGroupRO.id = ''; + const findAllUsersInGroup = await request(app.getHttpServer()) + .get(`/group/users/${createGroupRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(findAllUsersInGroup.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'PUT /group/user/:slug'; test.serial(`${currentTest} should return a group with new added user`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - firstUserToken, - undefined, - app, - undefined, - ); - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: createGroupRO.id, - }; - const findAllUsersInGroup = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const result = JSON.parse(findAllUsersInGroup.text).group; - t.is(findAllUsersInGroup.status, 200); - - t.is(result.title, newGroup1.title); - t.is(result.users.length, 2); - t.is(typeof result.users[1], 'object'); - - t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); - // t.is(result.users[0].isActive).toBe(true); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + firstUserToken, + undefined, + app, + undefined, + ); + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: createGroupRO.id, + }; + const findAllUsersInGroup = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const result = JSON.parse(findAllUsersInGroup.text).group; + t.is(findAllUsersInGroup.status, 200); + + t.is(result.title, newGroup1.title); + t.is(result.users.length, 2); + t.is(typeof result.users[1], 'object'); + + t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); + // t.is(result.users[0].isActive).toBe(true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when groupId not passed in request`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - firstUserToken, - undefined, - app, - undefined, - ); - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: undefined, - }; - const addUserInGroup = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup.status, 400); - const { message } = JSON.parse(addUserInGroup.text); - t.is(message, Messages.GROUP_ID_MISSING); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + firstUserToken, + undefined, + app, + undefined, + ); + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: undefined, + }; + const addUserInGroup = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup.status, 400); + const { message } = JSON.parse(addUserInGroup.text); + t.is(message, Messages.GROUP_ID_MISSING); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when user email not passed in request`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - const requestBody = { - email: undefined, - groupId: createGroupRO.id, - }; - const addUserInGroup = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup.status, 400); - const _responseObject = JSON.parse(addUserInGroup.text); - // t.is(responseObject.message, ErrorsMessages.VALIDATION_FAILED); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + const requestBody = { + email: undefined, + groupId: createGroupRO.id, + }; + const addUserInGroup = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup.status, 400); + const _responseObject = JSON.parse(addUserInGroup.text); + // t.is(responseObject.message, ErrorsMessages.VALIDATION_FAILED); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when groupId is incorrect`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - firstUserToken, - undefined, - app, - undefined, - ); - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - createGroupRO.id = faker.string.uuid(); - - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: createGroupRO.id, - }; - const addUserInGroup = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup.status, 400); - const { message } = JSON.parse(addUserInGroup.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + firstUserToken, + undefined, + app, + undefined, + ); + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + createGroupRO.id = faker.string.uuid(); + + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: createGroupRO.id, + }; + const addUserInGroup = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup.status, 400); + const { message } = JSON.parse(addUserInGroup.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when add a user what been already added in this group`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - firstUserToken, - undefined, - app, - undefined, - ); - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - let createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - createConnectionRO = JSON.parse(createConnectionResponse.text); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: createGroupRO.id, - }; - - const addUserInGroup1 = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup1.status, 200); - - const addUserInGroup2 = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup2.status, 400); - const { message } = JSON.parse(addUserInGroup2.text); - t.is(message, Messages.USER_ALREADY_ADDED); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + firstUserToken, + undefined, + app, + undefined, + ); + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + let createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + createConnectionRO = JSON.parse(createConnectionResponse.text); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: createGroupRO.id, + }; + + const addUserInGroup1 = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup1.status, 200); + + const addUserInGroup2 = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup2.status, 400); + const { message } = JSON.parse(addUserInGroup2.text); + t.is(message, Messages.USER_ALREADY_ADDED); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'DELETE /group'; test.serial(`${currentTest} should return an delete result`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - const deleteResult = await request(app.getHttpServer()) - .delete(`/group/${createGroupRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const deleteResultRO = JSON.parse(deleteResult.text); - t.is(deleteResult.status, 200); - t.is(typeof deleteResult, 'object'); - t.is(deleteResultRO.isMain, false); - - const response = await request(app.getHttpServer()) - .get(`/connection/groups/${createConnectionRO.id}`) - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(response.status, 200); - const result = JSON.parse(response.text); - const _groupId = result[0].group.id; - t.is(result.length, 1); - - t.is(result[0].group.title, 'Admin'); - t.is(result[0].accessLevel, AccessLevelEnum.edit); - - const index = result - .map((e) => { - return e.group.title; - }) - .indexOf('Admin'); - - t.is(index >= 0, true); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + const deleteResult = await request(app.getHttpServer()) + .delete(`/group/${createGroupRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const deleteResultRO = JSON.parse(deleteResult.text); + t.is(deleteResult.status, 200); + t.is(typeof deleteResult, 'object'); + t.is(deleteResultRO.isMain, false); + + const response = await request(app.getHttpServer()) + .get(`/connection/groups/${createConnectionRO.id}`) + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(response.status, 200); + const result = JSON.parse(response.text); + const _groupId = result[0].group.id; + t.is(result.length, 1); + + t.is(result[0].group.title, 'Admin'); + t.is(result[0].accessLevel, AccessLevelEnum.edit); + + const index = result + .map((e) => { + return e.group.title; + }) + .indexOf('Admin'); + + t.is(index >= 0, true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return throw an exception when groupId is incorrect`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - createGroupRO.id = faker.string.uuid(); - const deleteResult = await request(app.getHttpServer()) - .delete(`/group/${createGroupRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteResult.status, 400); - const { message } = JSON.parse(deleteResult.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + createGroupRO.id = faker.string.uuid(); + const deleteResult = await request(app.getHttpServer()) + .delete(`/group/${createGroupRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteResult.status, 400); + const { message } = JSON.parse(deleteResult.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when groupId is not passed in request`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - createGroupRO.id = ''; - const deleteResult = await request(app.getHttpServer()) - .delete(`/group/${createGroupRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteResult.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + createGroupRO.id = ''; + const deleteResult = await request(app.getHttpServer()) + .delete(`/group/${createGroupRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteResult.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'PUT /group/user/delete'; test.serial(`${currentTest} should return a group without deleted user`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - firstUserToken, - undefined, - app, - undefined, - ); - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: createGroupRO.id, - }; - const addUserInGroup = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup.status, 200); - let result = JSON.parse(addUserInGroup.text).group; - - t.is(result.title, newGroup1.title); - t.is(result.users.length, 2); - t.is(typeof result.users[1], 'object'); - - t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); - // t.is(result.users[0].isActive).toBe(true); - - const removeUserFromGroup = await request(app.getHttpServer()) - .put(`/group/user/delete/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - result = JSON.parse(removeUserFromGroup.text); - - t.is(typeof result, 'object'); - t.is(result.title, newGroup1.title); - - t.is(Object.hasOwn(result, 'users'), true); - t.is(typeof result.users, 'object'); - t.is(result.users.length, 1); - - // t.is(result.users[0].isActive).toBe(true); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + firstUserToken, + undefined, + app, + undefined, + ); + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: createGroupRO.id, + }; + const addUserInGroup = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup.status, 200); + let result = JSON.parse(addUserInGroup.text).group; + + t.is(result.title, newGroup1.title); + t.is(result.users.length, 2); + t.is(typeof result.users[1], 'object'); + + t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); + // t.is(result.users[0].isActive).toBe(true); + + const removeUserFromGroup = await request(app.getHttpServer()) + .put(`/group/user/delete/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + result = JSON.parse(removeUserFromGroup.text); + + t.is(typeof result, 'object'); + t.is(result.title, newGroup1.title); + + t.is(Object.hasOwn(result, 'users'), true); + t.is(typeof result.users, 'object'); + t.is(result.users.length, 1); + + // t.is(result.users[0].isActive).toBe(true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error, when group id not passed in request`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - firstUserToken, - undefined, - app, - undefined, - ); - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: createGroupRO.id, - }; - const addUserInGroup = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup.status, 200); - const result = JSON.parse(addUserInGroup.text).group; - - t.is(result.title, newGroup1.title); - t.is(result.users.length, 2); - t.is(typeof result.users[1], 'object'); - - t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); - // t.is(result.users[0].isActive).toBe(true); - - requestBody.groupId = undefined; - const removeUserFromGroup = await request(app.getHttpServer()) - .put(`/group/user/delete/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(removeUserFromGroup.text); - t.is(removeUserFromGroup.status, 400); - t.is(message, Messages.GROUP_ID_MISSING); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + firstUserToken, + undefined, + app, + undefined, + ); + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: createGroupRO.id, + }; + const addUserInGroup = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup.status, 200); + const result = JSON.parse(addUserInGroup.text).group; + + t.is(result.title, newGroup1.title); + t.is(result.users.length, 2); + t.is(typeof result.users[1], 'object'); + + t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); + // t.is(result.users[0].isActive).toBe(true); + + requestBody.groupId = undefined; + const removeUserFromGroup = await request(app.getHttpServer()) + .put(`/group/user/delete/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(removeUserFromGroup.text); + t.is(removeUserFromGroup.status, 400); + t.is(message, Messages.GROUP_ID_MISSING); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error, when email is not passed in request`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - firstUserToken, - undefined, - app, - undefined, - ); - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: createGroupRO.id, - }; - const addUserInGroup = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup.status, 200); - const result = JSON.parse(addUserInGroup.text).group; - - t.is(result.title, newGroup1.title); - t.is(result.users.length, 2); - t.is(typeof result.users[1], 'object'); - - t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); - // t.is(result.users[0].isActive).toBe(true); - - requestBody.email = undefined; - const removeUserFromGroup = await request(app.getHttpServer()) - .put(`/group/user/delete/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(removeUserFromGroup.text); - t.is(removeUserFromGroup.status, 400); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + firstUserToken, + undefined, + app, + undefined, + ); + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: createGroupRO.id, + }; + const addUserInGroup = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup.status, 200); + const result = JSON.parse(addUserInGroup.text).group; + + t.is(result.title, newGroup1.title); + t.is(result.users.length, 2); + t.is(typeof result.users[1], 'object'); + + t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); + // t.is(result.users[0].isActive).toBe(true); + + requestBody.email = undefined; + const removeUserFromGroup = await request(app.getHttpServer()) + .put(`/group/user/delete/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(removeUserFromGroup.text); + t.is(removeUserFromGroup.status, 400); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error, when there is no this email in database`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - firstUserToken, - undefined, - app, - undefined, - ); - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: createGroupRO.id, - }; - - const addUserInGroup = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup.status, 200); - - requestBody.email = faker.internet.email(); - const removeUserFromGroup = await request(app.getHttpServer()) - .put(`/group/user/delete/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(removeUserFromGroup.text); - t.is(removeUserFromGroup.status, 400); - t.is(message, Messages.USER_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + firstUserToken, + undefined, + app, + undefined, + ); + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: createGroupRO.id, + }; + + const addUserInGroup = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup.status, 200); + + requestBody.email = faker.internet.email(); + const removeUserFromGroup = await request(app.getHttpServer()) + .put(`/group/user/delete/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(removeUserFromGroup.text); + t.is(removeUserFromGroup.status, 400); + t.is(message, Messages.USER_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error, when group id is incorrect`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - firstUserToken, - undefined, - app, - undefined, - ); - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: createGroupRO.id, - }; - const addUserInGroup = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup.status, 200); - const result = JSON.parse(addUserInGroup.text).group; - - t.is(result.title, newGroup1.title); - t.is(result.users.length, 2); - t.is(typeof result.users[1], 'object'); - - t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); - - requestBody.groupId = faker.string.uuid(); - const removeUserFromGroup = await request(app.getHttpServer()) - .put(`/group/user/delete/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(removeUserFromGroup.text); - t.is(removeUserFromGroup.status, 400); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + firstUserToken, + undefined, + app, + undefined, + ); + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: createGroupRO.id, + }; + const addUserInGroup = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup.status, 200); + const result = JSON.parse(addUserInGroup.text).group; + + t.is(result.title, newGroup1.title); + t.is(result.users.length, 2); + t.is(typeof result.users[1], 'object'); + + t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); + + requestBody.groupId = faker.string.uuid(); + const removeUserFromGroup = await request(app.getHttpServer()) + .put(`/group/user/delete/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(removeUserFromGroup.text); + t.is(removeUserFromGroup.status, 400); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error, trying delete last user from admin group`, async (t) => { - try { - const firstUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const firstUserToken = firstUserRegisterInfo.token; - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const _createGroupRO = JSON.parse(createGroupResponse.text); - const groupId = createConnectionRO.groups[0].id; - const requestBody = { - email: firstUserRegisterInfo.email, - groupId: groupId, - }; - - const removeUserFromGroup = await request(app.getHttpServer()) - .put(`/group/user/delete/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(removeUserFromGroup.text); - t.is(removeUserFromGroup.status, 403); - t.is(message, Messages.CANT_DELETE_LAST_USER); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const firstUserToken = firstUserRegisterInfo.token; + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const _createGroupRO = JSON.parse(createGroupResponse.text); + const groupId = createConnectionRO.groups[0].id; + const requestBody = { + email: firstUserRegisterInfo.email, + groupId: groupId, + }; + + const removeUserFromGroup = await request(app.getHttpServer()) + .put(`/group/user/delete/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(removeUserFromGroup.text); + t.is(removeUserFromGroup.status, 403); + t.is(message, Messages.CANT_DELETE_LAST_USER); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'PUT /group/title/'; test.serial(`${currentTest} should return a group with new title`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - const groupId = createGroupRO.id; - - const groupUpdateData = { - title: 'Updated title', - groupId: groupId, - }; - - const updateGroupResponse = await request(app.getHttpServer()) - .put(`/group/title/`) - .send(groupUpdateData) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(updateGroupResponse.status, 200); - - const updateGroupTitleRO = JSON.parse(updateGroupResponse.text); - t.is(updateGroupTitleRO.title, groupUpdateData.title); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + const groupId = createGroupRO.id; + + const groupUpdateData = { + title: 'Updated title', + groupId: groupId, + }; + + const updateGroupResponse = await request(app.getHttpServer()) + .put(`/group/title/`) + .send(groupUpdateData) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(updateGroupResponse.status, 200); + + const updateGroupTitleRO = JSON.parse(updateGroupResponse.text); + t.is(updateGroupTitleRO.title, groupUpdateData.title); + } catch (e) { + console.error(e); + throw e; + } }); diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-permissions-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-permissions-e2e.test.ts index c8de72090..2debda81f 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-permissions-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-permissions-e2e.test.ts @@ -11,7 +11,10 @@ import { DatabaseModule } from '../../../src/shared/database/database.module.js' import { DatabaseService } from '../../../src/shared/database/database.service.js'; import cookieParser from 'cookie-parser'; import { AllExceptionsFilter } from '../../../src/exceptions/all-exceptions.filter.js'; -import { registerUserAndReturnUserInfo, createInitialTestUser } from '../../utils/register-user-and-return-user-info.js'; +import { + registerUserAndReturnUserInfo, + createInitialTestUser, +} from '../../utils/register-user-and-return-user-info.js'; import { getTestData } from '../../utils/get-test-data.js'; import request from 'supertest'; import { AccessLevelEnum } from '../../../src/enums/index.js'; @@ -28,259 +31,259 @@ let _testUtils: TestUtils; const mockFactory = new MockFactory(); test.before(async () => { - setSaasEnvVariable(); - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); + setSaasEnvVariable(); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - await createInitialTestUser(app); - app.getHttpServer().listen(0); + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + await createInitialTestUser(app); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); let currentTest = 'PUT permissions/:slug'; test.serial(`${currentTest} should return created permissions`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { newConnectionInDocker, newGroup1 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnectionInDocker) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { newConnectionInDocker, newGroup1 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnectionInDocker) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createGroupRO = JSON.parse(createGroupResponse.text); - t.is(createGroupResponse.status, 201); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + t.is(createGroupResponse.status, 201); - let connectionAccessLevel = AccessLevelEnum.none; - let groupAccesssLevel = AccessLevelEnum.edit; - let permissionsDTO = mockFactory.generateInternalPermissions( - createConnectionRO.id, - createGroupRO.id, - connectionAccessLevel, - groupAccesssLevel, - ); - let createPermissionsResponse = await request(app.getHttpServer()) - .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) - .send(permissionsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); + let connectionAccessLevel = AccessLevelEnum.none; + let groupAccesssLevel = AccessLevelEnum.edit; + let permissionsDTO = mockFactory.generateInternalPermissions( + createConnectionRO.id, + createGroupRO.id, + connectionAccessLevel, + groupAccesssLevel, + ); + let createPermissionsResponse = await request(app.getHttpServer()) + .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) + .send(permissionsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - let createPermissionsRO = JSON.parse(createPermissionsResponse.text); - t.is(createPermissionsResponse.status, 200); + let createPermissionsRO = JSON.parse(createPermissionsResponse.text); + t.is(createPermissionsResponse.status, 200); - let { connection: connectionDTO, group: groupDTO, tables: tablesDTO } = permissionsDTO.permissions; - let { connection, group, tables } = createPermissionsRO; - t.is(connection.accessLevel, connectionDTO.accessLevel); - t.is(group.accessLevel, groupDTO.accessLevel); - t.is(connection.connectionId, connectionDTO.connectionId); - t.is(group.groupId, groupDTO.groupId); - for (const table of tables) { - const tableInDto = tablesDTO.find((t) => t.tableName === table.tableName); - for (const key in table.accessLevel) { - t.is(table.accessLevel[key], tableInDto.accessLevel[key]); - } - } + let { connection: connectionDTO, group: groupDTO, tables: tablesDTO } = permissionsDTO.permissions; + let { connection, group, tables } = createPermissionsRO; + t.is(connection.accessLevel, connectionDTO.accessLevel); + t.is(group.accessLevel, groupDTO.accessLevel); + t.is(connection.connectionId, connectionDTO.connectionId); + t.is(group.groupId, groupDTO.groupId); + for (const table of tables) { + const tableInDto = tablesDTO.find((t) => t.tableName === table.tableName); + for (const key in table.accessLevel) { + t.is(table.accessLevel[key], tableInDto.accessLevel[key]); + } + } - connectionAccessLevel = AccessLevelEnum.readonly; - groupAccesssLevel = AccessLevelEnum.none; - permissionsDTO = mockFactory.generateInternalPermissions( - createConnectionRO.id, - createGroupRO.id, - connectionAccessLevel, - groupAccesssLevel, - ); + connectionAccessLevel = AccessLevelEnum.readonly; + groupAccesssLevel = AccessLevelEnum.none; + permissionsDTO = mockFactory.generateInternalPermissions( + createConnectionRO.id, + createGroupRO.id, + connectionAccessLevel, + groupAccesssLevel, + ); - createPermissionsResponse = await request(app.getHttpServer()) - .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) - .send(permissionsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - createPermissionsRO = JSON.parse(createPermissionsResponse.text); - t.is(createPermissionsResponse.status, 200); + createPermissionsResponse = await request(app.getHttpServer()) + .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) + .send(permissionsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + createPermissionsRO = JSON.parse(createPermissionsResponse.text); + t.is(createPermissionsResponse.status, 200); - t.is(createPermissionsRO.connection.accessLevel, connectionAccessLevel); + t.is(createPermissionsRO.connection.accessLevel, connectionAccessLevel); - t.is(createPermissionsRO.group.accessLevel, groupAccesssLevel); + t.is(createPermissionsRO.group.accessLevel, groupAccesssLevel); - tables = createPermissionsRO.tables; - tablesDTO = permissionsDTO.permissions.tables; - for (const table of tables) { - const tableInDto = tablesDTO.find((t) => t.tableName === table.tableName); - for (const key in table.accessLevel) { - t.is(table.accessLevel[key], tableInDto.accessLevel[key]); - } - } - } catch (e) { - console.error(e); - throw e; - } + tables = createPermissionsRO.tables; + tablesDTO = permissionsDTO.permissions.tables; + for (const table of tables) { + const tableInDto = tablesDTO.find((t) => t.tableName === table.tableName); + for (const key in table.accessLevel) { + t.is(table.accessLevel[key], tableInDto.accessLevel[key]); + } + } + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when groupId not passed`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { newConnectionInDocker, newGroup1 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnectionInDocker) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - let createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { newConnectionInDocker, newGroup1 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnectionInDocker) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + let createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createGroupRO = JSON.parse(createGroupResponse.text); - t.is(createGroupResponse.status, 201); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + t.is(createGroupResponse.status, 201); - let connectionAccessLevel = AccessLevelEnum.none; - let groupAccesssLevel = AccessLevelEnum.edit; - let permissionsDTO = mockFactory.generateInternalPermissions( - createConnectionRO.id, - createGroupRO.id, - connectionAccessLevel, - groupAccesssLevel, - ); - createGroupRO.id = ''; - let createPermissionsResponse = await request(app.getHttpServer()) - .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) - .send(permissionsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createPermissionsResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + let connectionAccessLevel = AccessLevelEnum.none; + let groupAccesssLevel = AccessLevelEnum.edit; + let permissionsDTO = mockFactory.generateInternalPermissions( + createConnectionRO.id, + createGroupRO.id, + connectionAccessLevel, + groupAccesssLevel, + ); + createGroupRO.id = ''; + let createPermissionsResponse = await request(app.getHttpServer()) + .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) + .send(permissionsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createPermissionsResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when groupId passed in request is incorrect`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { newConnectionInDocker, newGroup1 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnectionInDocker) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - let createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { newConnectionInDocker, newGroup1 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnectionInDocker) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + let createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createGroupRO = JSON.parse(createGroupResponse.text); - t.is(createGroupResponse.status, 201); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + t.is(createGroupResponse.status, 201); - let connectionAccessLevel = AccessLevelEnum.none; - let groupAccesssLevel = AccessLevelEnum.edit; - let permissionsDTO = mockFactory.generateInternalPermissions( - createConnectionRO.id, - createGroupRO.id, - connectionAccessLevel, - groupAccesssLevel, - ); - createGroupRO.id = faker.string.uuid(); - let createPermissionsResponse = await request(app.getHttpServer()) - .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) - .send(permissionsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createPermissionsResponse.status, 400); - const { message } = JSON.parse(createPermissionsResponse.text); - t.is(message, Messages.GROUP_NOT_FROM_THIS_CONNECTION); - } catch (e) { - console.error(e); - throw e; - } + let connectionAccessLevel = AccessLevelEnum.none; + let groupAccesssLevel = AccessLevelEnum.edit; + let permissionsDTO = mockFactory.generateInternalPermissions( + createConnectionRO.id, + createGroupRO.id, + connectionAccessLevel, + groupAccesssLevel, + ); + createGroupRO.id = faker.string.uuid(); + let createPermissionsResponse = await request(app.getHttpServer()) + .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) + .send(permissionsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createPermissionsResponse.status, 400); + const { message } = JSON.parse(createPermissionsResponse.text); + t.is(message, Messages.GROUP_NOT_FROM_THIS_CONNECTION); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when connectionId is incorrect`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { newConnectionInDocker, newGroup1 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnectionInDocker) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - let createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { newConnectionInDocker, newGroup1 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnectionInDocker) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + let createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createGroupRO = JSON.parse(createGroupResponse.text); - t.is(createGroupResponse.status, 201); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + t.is(createGroupResponse.status, 201); - let connectionAccessLevel = AccessLevelEnum.none; - let groupAccesssLevel = AccessLevelEnum.edit; - let permissionsDTO = mockFactory.generateInternalPermissions( - createConnectionRO.id, - createGroupRO.id, - connectionAccessLevel, - groupAccesssLevel, - ); - permissionsDTO.permissions.connection.connectionId = faker.string.uuid(); - let createPermissionsResponse = await request(app.getHttpServer()) - .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) - .send(permissionsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createPermissionsResponse.status, 400); - const { message } = JSON.parse(createPermissionsResponse.text); - t.is(message, Messages.GROUP_NOT_FROM_THIS_CONNECTION); - } catch (e) { - console.error(e); - throw e; - } + let connectionAccessLevel = AccessLevelEnum.none; + let groupAccesssLevel = AccessLevelEnum.edit; + let permissionsDTO = mockFactory.generateInternalPermissions( + createConnectionRO.id, + createGroupRO.id, + connectionAccessLevel, + groupAccesssLevel, + ); + permissionsDTO.permissions.connection.connectionId = faker.string.uuid(); + let createPermissionsResponse = await request(app.getHttpServer()) + .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) + .send(permissionsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createPermissionsResponse.status, 400); + const { message } = JSON.parse(createPermissionsResponse.text); + t.is(message, Messages.GROUP_NOT_FROM_THIS_CONNECTION); + } catch (e) { + console.error(e); + throw e; + } }); diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-postgres-with-binary-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-postgres-with-binary-e2e.test.ts index 05d8bca69..e3970e3c0 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-postgres-with-binary-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-postgres-with-binary-e2e.test.ts @@ -13,7 +13,10 @@ import { DatabaseModule } from '../../../src/shared/database/database.module.js' import { DatabaseService } from '../../../src/shared/database/database.service.js'; import { MockFactory } from '../../mock.factory.js'; import { getTestData } from '../../utils/get-test-data.js'; -import { registerUserAndReturnUserInfo, createInitialTestUser } from '../../utils/register-user-and-return-user-info.js'; +import { + registerUserAndReturnUserInfo, + createInitialTestUser, +} from '../../utils/register-user-and-return-user-info.js'; import { TestUtils } from '../../utils/test.utils.js'; import { getTestKnex } from '../../utils/get-test-knex.js'; import { hexToBinary } from '../../../src/helpers/binary-to-hex.js'; @@ -29,109 +32,109 @@ let _testUtils: TestUtils; let currentTest; test.before(async () => { - setSaasEnvVariable(); - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - await createInitialTestUser(app); - app.getHttpServer().listen(0); + setSaasEnvVariable(); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + await createInitialTestUser(app); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = ''; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const connectionParamsCopy = { - ...connectionToTestDB, - }; - - const testTableName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; - const testTableColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; - const testTableSecondColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; - const Knex = getTestKnex(connectionParamsCopy); - await Knex.schema.createTable(testTableName, (table) => { - table.increments(); - table.binary(testTableColumnName); - table.string(testTableSecondColumnName); - table.timestamps(); - }); - - const testDataForInsert = { - [testTableColumnName]: hexToBinary('6168616c6169206d6168616c6169'), - [testTableSecondColumnName]: 'test', - }; - - await Knex(testTableName).insert({ - ...testDataForInsert, - }); - - for (let i = 0; i < 8; i++) { - await Knex(testTableName).insert({ - [testTableColumnName]: hexToBinary(`6168616c616${i}206d6168616c6169`), - [testTableSecondColumnName]: `test_${i}`, - }); - } - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - const getTableRowsWithSearchResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${getTableRowsRO.rows[0][testTableColumnName]}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsWithSearchRO = JSON.parse(getTableRowsWithSearchResponse.text); - t.is(getTableRowsResponse.status, 200); - t.is(getTableRowsWithSearchRO.rows.length, 1); - t.is(getTableRowsWithSearchRO.rows[0][testTableColumnName], getTableRowsRO.rows[0][testTableColumnName]); - - t.pass(); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const connectionParamsCopy = { + ...connectionToTestDB, + }; + + const testTableName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; + const testTableColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; + const testTableSecondColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; + const Knex = getTestKnex(connectionParamsCopy); + await Knex.schema.createTable(testTableName, (table) => { + table.increments(); + table.binary(testTableColumnName); + table.string(testTableSecondColumnName); + table.timestamps(); + }); + + const testDataForInsert = { + [testTableColumnName]: hexToBinary('6168616c6169206d6168616c6169'), + [testTableSecondColumnName]: 'test', + }; + + await Knex(testTableName).insert({ + ...testDataForInsert, + }); + + for (let i = 0; i < 8; i++) { + await Knex(testTableName).insert({ + [testTableColumnName]: hexToBinary(`6168616c616${i}206d6168616c6169`), + [testTableSecondColumnName]: `test_${i}`, + }); + } + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + const getTableRowsWithSearchResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${getTableRowsRO.rows[0][testTableColumnName]}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsWithSearchRO = JSON.parse(getTableRowsWithSearchResponse.text); + t.is(getTableRowsResponse.status, 200); + t.is(getTableRowsWithSearchRO.rows.length, 1); + t.is(getTableRowsWithSearchRO.rows[0][testTableColumnName], getTableRowsRO.rows[0][testTableColumnName]); + + t.pass(); + } catch (e) { + console.error(e); + throw e; + } }); diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-table-mysql-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-table-mysql-e2e.test.ts index b099895e0..289e4788c 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-table-mysql-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-table-mysql-e2e.test.ts @@ -18,7 +18,10 @@ import { MockFactory } from '../../mock.factory.js'; import { createTestTable } from '../../utils/create-test-table.js'; import { dropTestTables } from '../../utils/drop-test-tables.js'; import { getTestData } from '../../utils/get-test-data.js'; -import { registerUserAndReturnUserInfo, createInitialTestUser } from '../../utils/register-user-and-return-user-info.js'; +import { + registerUserAndReturnUserInfo, + createInitialTestUser, +} from '../../utils/register-user-and-return-user-info.js'; import { TestUtils } from '../../utils/test.utils.js'; import { setSaasEnvVariable } from '../../utils/set-saas-env-variable.js'; import { ValidationException } from '../../../src/exceptions/custom-exceptions/validation-exception.js'; @@ -33,3630 +36,3630 @@ const testTables: Array = []; let currentTest; test.before(async () => { - setSaasEnvVariable(); - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - await createInitialTestUser(app); - app.getHttpServer().listen(0); + setSaasEnvVariable(); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + await createInitialTestUser(app); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - await dropTestTables(testTables, connectionToTestDB); - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + await dropTestTables(testTables, connectionToTestDB); + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /connection/tables/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 200); - const getTablesRO = JSON.parse(getTablesResponse.text); - - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.length > 0, true); - - const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); - - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); - t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); - t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); - t.is(getTablesRO[testTableIndex].table, testTableName); - t.is(getTablesRO[testTableIndex].permissions.visibility, true); - t.is(getTablesRO[testTableIndex].permissions.readonly, false); - t.is(getTablesRO[testTableIndex].permissions.add, true); - t.is(getTablesRO[testTableIndex].permissions.delete, true); - t.is(getTablesRO[testTableIndex].permissions.edit, true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 200); + const getTablesRO = JSON.parse(getTablesResponse.text); + + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.length > 0, true); + + const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); + + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); + t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); + t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); + t.is(getTablesRO[testTableIndex].table, testTableName); + t.is(getTablesRO[testTableIndex].permissions.visibility, true); + t.is(getTablesRO[testTableIndex].permissions.readonly, false); + t.is(getTablesRO[testTableIndex].permissions.add, true); + t.is(getTablesRO[testTableIndex].permissions.delete, true); + t.is(getTablesRO[testTableIndex].permissions.edit, true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connectionId not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = ''; - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = ''; + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connection id is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = faker.string.uuid(); - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 400); - const { message } = JSON.parse(getTablesResponse.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = faker.string.uuid(); + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 400); + const { message } = JSON.parse(getTablesResponse.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return rows of selected table without search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return rows of selected table with search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createTableSettingsResponse.status, 201); - - const searchedDescription = '25'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const searchedDescription = '25'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=1, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Content-Type', 'application/json') - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=3, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 3); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 3); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by DESC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - t.is(getTableRowsRO.rows[41].id, 1); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + t.is(getTableRowsRO.rows[41].id, 1); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by ASC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - t.is(getTableRowsRO.rows[41].id, 42); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + t.is(getTableRowsRO.rows[41].id, 42); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and with pagination and with sorting + `${currentTest} without search and with pagination and with sorting should return all found rows with sorting ports by DESC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 39); - t.is(getTableRowsRO.rows[1].id, 38); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 39); + t.is(getTableRowsRO.rows[1].id, 38); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '45'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '45'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=10 and DESC sorting and filtering'`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[2].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 10); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[2].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 10); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and with multi filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - createConnectionRO.id = ''; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + createConnectionRO.id = ''; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - createConnectionRO.id = faker.string.uuid(); - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 403); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + createConnectionRO.id = faker.string.uuid(); + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 403); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 400); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 400); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = faker.lorem.words(1); - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTablesRO = JSON.parse(getTableRowsResponse.text); - t.is(getTablesRO.rows.length, 2); - t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTablesRO, 'pagination'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = faker.lorem.words(1); + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTablesRO = JSON.parse(getTableRowsResponse.text); + t.is(getTablesRO.rows.length, 2); + t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTablesRO, 'pagination'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 200); - const getTableStructureRO = JSON.parse(getTableStructure.text); - - t.is(typeof getTableStructureRO, 'object'); - t.is(typeof getTableStructureRO.structure, 'object'); - t.is(getTableStructureRO.structure.length, 5); - - for (const element of getTableStructureRO.structure) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'column_default'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - t.is(Object.hasOwn(element, 'isExcluded'), true); - t.is(Object.hasOwn(element, 'isSearched'), true); - } - - t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); - - for (const element of getTableStructureRO.primaryColumns) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - } - - for (const element of getTableStructureRO.foreignKeys) { - t.is(Object.hasOwn(element, 'referenced_column_name'), true); - t.is(Object.hasOwn(element, 'referenced_table_name'), true); - t.is(Object.hasOwn(element, 'constraint_name'), true); - t.is(Object.hasOwn(element, 'column_name'), true); - } + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 200); + const getTableStructureRO = JSON.parse(getTableStructure.text); + + t.is(typeof getTableStructureRO, 'object'); + t.is(typeof getTableStructureRO.structure, 'object'); + t.is(getTableStructureRO.structure.length, 5); + + for (const element of getTableStructureRO.structure) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'column_default'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + t.is(Object.hasOwn(element, 'isExcluded'), true); + t.is(Object.hasOwn(element, 'isSearched'), true); + } + + t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); + + for (const element of getTableStructureRO.primaryColumns) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + } + + for (const element of getTableStructureRO.foreignKeys) { + t.is(Object.hasOwn(element, 'referenced_column_name'), true); + t.is(Object.hasOwn(element, 'referenced_table_name'), true); + t.is(Object.hasOwn(element, 'constraint_name'), true); + t.is(Object.hasOwn(element, 'column_name'), true); + } }); test.serial(`${currentTest} should throw an exception whe connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 404); }); test.serial(`${currentTest} should throw an exception whe connection id passed in request id incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = faker.string.uuid(); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 403); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = faker.string.uuid(); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 403); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest}should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = faker.lorem.words(1); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = faker.lorem.words(1); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should add row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addRowInTableRO = JSON.parse(addRowInTableResponse.text); - t.is(addRowInTableResponse.status, 201); - - t.is(Object.hasOwn(addRowInTableRO, 'row'), true); - t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); - t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 43); - t.is(rows[42][testTableColumnName], row[testTableColumnName]); - t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); - t.is(rows[42].id, rows[41].id + 1); - - // check that rows adding was logged - - const getLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getLogsResponse.status, 200); - const getLogsRO = JSON.parse(getLogsResponse.text); - t.is(Object.hasOwn(getLogsRO, 'logs'), true); - t.is(Object.hasOwn(getLogsRO, 'pagination'), true); - t.is(getLogsRO.logs.length > 0, true); - const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); - t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); - t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, 43); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addRowInTableRO = JSON.parse(addRowInTableResponse.text); + t.is(addRowInTableResponse.status, 201); + + t.is(Object.hasOwn(addRowInTableRO, 'row'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 43); + t.is(rows[42][testTableColumnName], row[testTableColumnName]); + t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); + t.is(rows[42].id, rows[41].id + 1); + + // check that rows adding was logged + + const getLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getLogsResponse.status, 200); + const getLogsRO = JSON.parse(getLogsResponse.text); + t.is(Object.hasOwn(getLogsRO, 'logs'), true); + t.is(Object.hasOwn(getLogsRO, 'pagination'), true); + t.is(getLogsRO.logs.length > 0, true); + const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); + t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); + t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, 43); }); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const fakeConnectionId = ''; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 404); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const fakeConnectionId = ''; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 404); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when row is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.PARAMETER_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.PARAMETER_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); currentTest = 'PUT /table/row/:slug'; test.serial(`${currentTest} should update row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 200); - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); - t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was updated - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - const updateRowIndex = rows.map((row) => row.id).indexOf(1); - t.is(rows.length, 42); - t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); - t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 200); + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); + t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was updated + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + const updateRowIndex = rows.map((row) => row.id).indexOf(1); + t.is(rows.length, 42); + t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); + t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = ''; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = ''; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 404); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 403); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 403); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 41); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, true); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 41); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, true); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 404); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 404); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = faker.string.uuid(); - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 403); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = faker.string.uuid(); + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 403); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - t.is(deleteRowInTableResponse.status, 400); - t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + t.is(deleteRowInTableResponse.status, 400); + t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} found row`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 200); - const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); - t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); - t.is(typeof foundRowInTableRO.row, 'object'); - t.is(typeof foundRowInTableRO.structure, 'object'); - t.is(typeof foundRowInTableRO.primaryColumns, 'object'); - t.is(typeof foundRowInTableRO.readonly_fields, 'object'); - t.is(typeof foundRowInTableRO.foreignKeys, 'object'); - t.is(foundRowInTableRO.row.id, 1); - t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); - t.is(Object.keys(foundRowInTableRO.row).length, 5); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 200); + const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); + t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); + t.is(typeof foundRowInTableRO.row, 'object'); + t.is(typeof foundRowInTableRO.structure, 'object'); + t.is(typeof foundRowInTableRO.primaryColumns, 'object'); + t.is(typeof foundRowInTableRO.readonly_fields, 'object'); + t.is(typeof foundRowInTableRO.foreignKeys, 'object'); + t.is(foundRowInTableRO.row.id, 1); + t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); + t.is(Object.keys(foundRowInTableRO.row).length, 5); }); test.serial(`${currentTest} should throw an exception, when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const idForSearch = 1; - createConnectionRO.id = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const idForSearch = 1; + createConnectionRO.id = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 404); }); test.serial( - `${currentTest} should throw an exception, when connection id passed in request is incorrect`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - createConnectionRO.id = faker.string.uuid(); - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 403); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - }, + `${currentTest} should throw an exception, when connection id passed in request is incorrect`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + createConnectionRO.id = faker.string.uuid(); + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 403); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + }, ); test.serial(`${currentTest} should throw an exception, when tableName in not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception, when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception, when primary key is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1000000; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1000000; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/delete/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const primaryKeysForDeletion: Array> = [ - { - id: 1, - }, - { - id: 10, - }, - { - id: 32, - }, - ]; - const deleteRowsInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) - .send(primaryKeysForDeletion) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowsInTableResponse.status, 200); - const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - // check that lines was deleted - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); - - for (const key of primaryKeysForDeletion) { - t.is( - rows.findIndex((row) => row.id === key.id), - -1, - ); - } - - // check that table deletaion was logged - const tableLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(tableLogsResponse.status, 200); - - const tableLogsRO = JSON.parse(tableLogsResponse.text); - t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); - const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); - for (const key of primaryKeysForDeletion) { - t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); - } + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const primaryKeysForDeletion: Array> = [ + { + id: 1, + }, + { + id: 10, + }, + { + id: 32, + }, + ]; + const deleteRowsInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) + .send(primaryKeysForDeletion) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowsInTableResponse.status, 200); + const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + // check that lines was deleted + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); + + for (const key of primaryKeysForDeletion) { + t.is( + rows.findIndex((row) => row.id === key.id), + -1, + ); + } + + // check that table deletaion was logged + const tableLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(tableLogsResponse.status, 200); + + const tableLogsRO = JSON.parse(tableLogsResponse.text); + t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); + const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); + for (const key of primaryKeysForDeletion) { + t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); + } }); test.serial(`${currentTest} should test connection and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const testConnectionResponse = await request(app.getHttpServer()) - .post('/connection/test/') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse.status, 201); - const { message } = JSON.parse(testConnectionResponse.text); - t.is(message, 'Successfully connected'); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const testConnectionResponse = await request(app.getHttpServer()) + .post('/connection/test/') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse.status, 201); + const { message } = JSON.parse(testConnectionResponse.text); + t.is(message, 'Successfully connected'); }); diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-table-oracledb-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-table-oracledb-e2e.test.ts index 5e87a4924..f3c410b5a 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-table-oracledb-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-table-oracledb-e2e.test.ts @@ -18,7 +18,10 @@ import { MockFactory } from '../../mock.factory.js'; import { createTestOracleTable } from '../../utils/create-test-table.js'; import { dropTestTables } from '../../utils/drop-test-tables.js'; import { getTestData } from '../../utils/get-test-data.js'; -import { registerUserAndReturnUserInfo, createInitialTestUser } from '../../utils/register-user-and-return-user-info.js'; +import { + registerUserAndReturnUserInfo, + createInitialTestUser, +} from '../../utils/register-user-and-return-user-info.js'; import { TestUtils } from '../../utils/test.utils.js'; import { setSaasEnvVariable } from '../../utils/set-saas-env-variable.js'; import { ValidationException } from '../../../src/exceptions/custom-exceptions/validation-exception.js'; @@ -33,3625 +36,3625 @@ const testTables: Array = []; let currentTest; test.before(async () => { - setSaasEnvVariable(); - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - await createInitialTestUser(app); - app.getHttpServer().listen(0); + setSaasEnvVariable(); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + await createInitialTestUser(app); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - await dropTestTables(testTables, connectionToTestDB); - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + await dropTestTables(testTables, connectionToTestDB); + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /connection/tables/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTablesRO = JSON.parse(getTablesResponse.text); - t.is(getTablesResponse.status, 200); - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.length > 0, true); - - const testTableIndex = getTablesRO.findIndex((t) => { - return t.table === testTableName; - }); - - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); - t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); - t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); - t.is(getTablesRO[testTableIndex].table, testTableName); - t.is(getTablesRO[testTableIndex].permissions.visibility, true); - t.is(getTablesRO[testTableIndex].permissions.readonly, false); - t.is(getTablesRO[testTableIndex].permissions.add, true); - t.is(getTablesRO[testTableIndex].permissions.delete, true); - t.is(getTablesRO[testTableIndex].permissions.edit, true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTablesRO = JSON.parse(getTablesResponse.text); + t.is(getTablesResponse.status, 200); + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.length > 0, true); + + const testTableIndex = getTablesRO.findIndex((t) => { + return t.table === testTableName; + }); + + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); + t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); + t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); + t.is(getTablesRO[testTableIndex].table, testTableName); + t.is(getTablesRO[testTableIndex].permissions.visibility, true); + t.is(getTablesRO[testTableIndex].permissions.readonly, false); + t.is(getTablesRO[testTableIndex].permissions.add, true); + t.is(getTablesRO[testTableIndex].permissions.delete, true); + t.is(getTablesRO[testTableIndex].permissions.edit, true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connectionId not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = ''; - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = ''; + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connection id is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = faker.string.uuid(); - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 400); - const { message } = JSON.parse(getTablesResponse.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = faker.string.uuid(); + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 400); + const { message } = JSON.parse(getTablesResponse.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return rows of selected table without search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return rows of selected table with search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createTableSettingsResponse.status, 201); - - const searchedDescription = '25'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const searchedDescription = '25'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=1, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Content-Type', 'application/json') - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=3, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 3); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 3); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - // t.is(getTableRowsRO.pagination.total, 42); - // t.is(getTableRowsRO.pagination.lastPage, 2); - // t.is(getTableRowsRO.pagination.perPage, 2); - // t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + // t.is(getTableRowsRO.pagination.total, 42); + // t.is(getTableRowsRO.pagination.lastPage, 2); + // t.is(getTableRowsRO.pagination.perPage, 2); + // t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - // t.is(getTableRowsRO.pagination.total, 42); - // t.is(getTableRowsRO.pagination.lastPage, 2); - // t.is(getTableRowsRO.pagination.perPage, 2); - // t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + // t.is(getTableRowsRO.pagination.total, 42); + // t.is(getTableRowsRO.pagination.lastPage, 2); + // t.is(getTableRowsRO.pagination.perPage, 2); + // t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by DESC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - t.is(getTableRowsRO.rows[41].id, 1); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + t.is(getTableRowsRO.rows[41].id, 1); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by ASC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - t.is(getTableRowsRO.rows[41].id, 42); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + t.is(getTableRowsRO.rows[41].id, 42); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and with pagination and with sorting + `${currentTest} without search and with pagination and with sorting should return all found rows with sorting ports by DESC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 39); - t.is(getTableRowsRO.rows[1].id, 38); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 39); + t.is(getTableRowsRO.rows[1].id, 38); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '45'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '45'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=10 and DESC sorting and filtering'`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[2].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 10); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[2].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 10); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and with multi filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - createConnectionRO.id = ''; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + createConnectionRO.id = ''; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - createConnectionRO.id = faker.string.uuid(); - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 403); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + createConnectionRO.id = faker.string.uuid(); + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 403); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 400); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 400); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = faker.lorem.words(1); - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTablesRO = JSON.parse(getTableRowsResponse.text); - t.is(getTablesRO.rows.length, 2); - t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTablesRO, 'pagination'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = faker.lorem.words(1); + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTablesRO = JSON.parse(getTableRowsResponse.text); + t.is(getTablesRO.rows.length, 2); + t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTablesRO, 'pagination'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 200); - const getTableStructureRO = JSON.parse(getTableStructure.text); - - t.is(typeof getTableStructureRO, 'object'); - t.is(typeof getTableStructureRO.structure, 'object'); - t.is(getTableStructureRO.structure.length, 5); - - for (const element of getTableStructureRO.structure) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'column_default'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - t.is(Object.hasOwn(element, 'isExcluded'), true); - t.is(Object.hasOwn(element, 'isSearched'), true); - } - - t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); - - for (const element of getTableStructureRO.primaryColumns) { - t.is(Object.hasOwn(element, 'column_name'), true); - // t.is(element.hasOwnProperty('data_type'), true); - } - - for (const element of getTableStructureRO.foreignKeys) { - t.is(Object.hasOwn(element, 'referenced_column_name'), true); - t.is(Object.hasOwn(element, 'referenced_table_name'), true); - t.is(Object.hasOwn(element, 'constraint_name'), true); - t.is(Object.hasOwn(element, 'column_name'), true); - } + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 200); + const getTableStructureRO = JSON.parse(getTableStructure.text); + + t.is(typeof getTableStructureRO, 'object'); + t.is(typeof getTableStructureRO.structure, 'object'); + t.is(getTableStructureRO.structure.length, 5); + + for (const element of getTableStructureRO.structure) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'column_default'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + t.is(Object.hasOwn(element, 'isExcluded'), true); + t.is(Object.hasOwn(element, 'isSearched'), true); + } + + t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); + + for (const element of getTableStructureRO.primaryColumns) { + t.is(Object.hasOwn(element, 'column_name'), true); + // t.is(element.hasOwnProperty('data_type'), true); + } + + for (const element of getTableStructureRO.foreignKeys) { + t.is(Object.hasOwn(element, 'referenced_column_name'), true); + t.is(Object.hasOwn(element, 'referenced_table_name'), true); + t.is(Object.hasOwn(element, 'constraint_name'), true); + t.is(Object.hasOwn(element, 'column_name'), true); + } }); test.serial(`${currentTest} should throw an exception whe connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 404); }); test.serial(`${currentTest} should throw an exception whe connection id passed in request id incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = faker.string.uuid(); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 403); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = faker.string.uuid(); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 403); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest}should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = faker.lorem.words(1); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = faker.lorem.words(1); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should add row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 43, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addRowInTableRO = JSON.parse(addRowInTableResponse.text); - t.is(addRowInTableResponse.status, 201); - - t.is(Object.hasOwn(addRowInTableRO, 'row'), true); - t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); - t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 43); - t.is(rows[42][testTableColumnName], row[testTableColumnName]); - t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); - t.is(rows[42].id, rows[41].id + 1); - - // check that rows adding was logged - - const getLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getLogsResponse.status, 200); - const getLogsRO = JSON.parse(getLogsResponse.text); - t.is(Object.hasOwn(getLogsRO, 'logs'), true); - t.is(Object.hasOwn(getLogsRO, 'pagination'), true); - t.is(getLogsRO.logs.length > 0, true); - const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); - t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); - t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, String(43)); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 43, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addRowInTableRO = JSON.parse(addRowInTableResponse.text); + t.is(addRowInTableResponse.status, 201); + + t.is(Object.hasOwn(addRowInTableRO, 'row'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 43); + t.is(rows[42][testTableColumnName], row[testTableColumnName]); + t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); + t.is(rows[42].id, rows[41].id + 1); + + // check that rows adding was logged + + const getLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getLogsResponse.status, 200); + const getLogsRO = JSON.parse(getLogsResponse.text); + t.is(Object.hasOwn(getLogsRO, 'logs'), true); + t.is(Object.hasOwn(getLogsRO, 'pagination'), true); + t.is(getLogsRO.logs.length > 0, true); + const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); + t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); + t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, String(43)); }); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const fakeConnectionId = ''; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 404); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const fakeConnectionId = ''; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 404); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when row is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.PARAMETER_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.PARAMETER_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); currentTest = 'PUT /table/row/:slug'; test.serial(`${currentTest} should update row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 200); - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); - t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was updated - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - const updateRowIndex = rows.map((row) => row.id).indexOf(1); - t.is(rows.length, 42); - t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); - t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 200); + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); + t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was updated + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + const updateRowIndex = rows.map((row) => row.id).indexOf(1); + t.is(rows.length, 42); + t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); + t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = ''; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = ''; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 404); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 403); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 403); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 41); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, true); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 41); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, true); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 404); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 404); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = faker.string.uuid(); - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 403); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = faker.string.uuid(); + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 403); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - t.is(deleteRowInTableResponse.status, 400); - t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + t.is(deleteRowInTableResponse.status, 400); + t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} found row`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); - t.is(foundRowInTableResponse.status, 200); - - t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); - t.is(typeof foundRowInTableRO.row, 'object'); - t.is(typeof foundRowInTableRO.structure, 'object'); - t.is(typeof foundRowInTableRO.primaryColumns, 'object'); - t.is(typeof foundRowInTableRO.readonly_fields, 'object'); - t.is(typeof foundRowInTableRO.foreignKeys, 'object'); - t.is(foundRowInTableRO.row.id, 1); - t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); - t.is(Object.keys(foundRowInTableRO.row).length, 5); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); + t.is(foundRowInTableResponse.status, 200); + + t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); + t.is(typeof foundRowInTableRO.row, 'object'); + t.is(typeof foundRowInTableRO.structure, 'object'); + t.is(typeof foundRowInTableRO.primaryColumns, 'object'); + t.is(typeof foundRowInTableRO.readonly_fields, 'object'); + t.is(typeof foundRowInTableRO.foreignKeys, 'object'); + t.is(foundRowInTableRO.row.id, 1); + t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); + t.is(Object.keys(foundRowInTableRO.row).length, 5); }); test.serial(`${currentTest} should throw an exception, when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const idForSearch = 1; - createConnectionRO.id = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const idForSearch = 1; + createConnectionRO.id = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 404); }); test.serial( - `${currentTest} should throw an exception, when connection id passed in request is incorrect`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - createConnectionRO.id = faker.string.uuid(); - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 403); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - }, + `${currentTest} should throw an exception, when connection id passed in request is incorrect`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + createConnectionRO.id = faker.string.uuid(); + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 403); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + }, ); test.serial(`${currentTest} should throw an exception, when tableName in not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception, when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception, when primary key is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1000000; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1000000; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/delete/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const primaryKeysForDeletion: Array> = [ - { - id: 1, - }, - { - id: 10, - }, - { - id: 32, - }, - ]; - const deleteRowsInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) - .send(primaryKeysForDeletion) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowsInTableResponse.status, 200); - const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - // check that lines was deleted - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); - - for (const key of primaryKeysForDeletion) { - t.is( - rows.findIndex((row) => row.id === key.id), - -1, - ); - } - - // check that table deletaion was logged - const tableLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(tableLogsResponse.status, 200); - - const tableLogsRO = JSON.parse(tableLogsResponse.text); - t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); - const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); - for (const key of primaryKeysForDeletion) { - t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); - } + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const primaryKeysForDeletion: Array> = [ + { + id: 1, + }, + { + id: 10, + }, + { + id: 32, + }, + ]; + const deleteRowsInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) + .send(primaryKeysForDeletion) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowsInTableResponse.status, 200); + const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + // check that lines was deleted + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); + + for (const key of primaryKeysForDeletion) { + t.is( + rows.findIndex((row) => row.id === key.id), + -1, + ); + } + + // check that table deletaion was logged + const tableLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(tableLogsResponse.status, 200); + + const tableLogsRO = JSON.parse(tableLogsResponse.text); + t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); + const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); + for (const key of primaryKeysForDeletion) { + t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); + } }); currentTest = 'POST /connection/test/'; test.serial(`${currentTest} should test connection and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const testConnectionResponse = await request(app.getHttpServer()) - .post('/connection/test/') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse.status, 201); - const { message } = JSON.parse(testConnectionResponse.text); - t.is(message, 'Successfully connected'); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const testConnectionResponse = await request(app.getHttpServer()) + .post('/connection/test/') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse.status, 201); + const { message } = JSON.parse(testConnectionResponse.text); + t.is(message, 'Successfully connected'); }); diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-table-oracledb-schema-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-table-oracledb-schema-e2e.test.ts index 5a14530d0..d6aa611e3 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-table-oracledb-schema-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-table-oracledb-schema-e2e.test.ts @@ -18,7 +18,10 @@ import { MockFactory } from '../../mock.factory.js'; import { createTestOracleTable } from '../../utils/create-test-table.js'; import { dropTestTables } from '../../utils/drop-test-tables.js'; import { getTestData } from '../../utils/get-test-data.js'; -import { registerUserAndReturnUserInfo, createInitialTestUser } from '../../utils/register-user-and-return-user-info.js'; +import { + registerUserAndReturnUserInfo, + createInitialTestUser, +} from '../../utils/register-user-and-return-user-info.js'; import { TestUtils } from '../../utils/test.utils.js'; import { setSaasEnvVariable } from '../../utils/set-saas-env-variable.js'; import { ValidationException } from '../../../src/exceptions/custom-exceptions/validation-exception.js'; @@ -33,3633 +36,3633 @@ const testTables: Array = []; let currentTest; test.before(async () => { - setSaasEnvVariable(); - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication() as any; - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - await createInitialTestUser(app); - app.getHttpServer().listen(0); + setSaasEnvVariable(); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication() as any; + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + await createInitialTestUser(app); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - await dropTestTables(testTables, connectionToTestDB); - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + await dropTestTables(testTables, connectionToTestDB); + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /connection/tables/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 200); - const getTablesRO = JSON.parse(getTablesResponse.text); - - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.length > 0, true); - - const testTableIndex = getTablesRO.findIndex((t) => { - return t.table === testTableName; - }); - - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); - t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); - t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); - t.is(getTablesRO[testTableIndex].table, testTableName); - t.is(getTablesRO[testTableIndex].permissions.visibility, true); - t.is(getTablesRO[testTableIndex].permissions.readonly, false); - t.is(getTablesRO[testTableIndex].permissions.add, true); - t.is(getTablesRO[testTableIndex].permissions.delete, true); - t.is(getTablesRO[testTableIndex].permissions.edit, true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 200); + const getTablesRO = JSON.parse(getTablesResponse.text); + + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.length > 0, true); + + const testTableIndex = getTablesRO.findIndex((t) => { + return t.table === testTableName; + }); + + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); + t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); + t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); + t.is(getTablesRO[testTableIndex].table, testTableName); + t.is(getTablesRO[testTableIndex].permissions.visibility, true); + t.is(getTablesRO[testTableIndex].permissions.readonly, false); + t.is(getTablesRO[testTableIndex].permissions.add, true); + t.is(getTablesRO[testTableIndex].permissions.delete, true); + t.is(getTablesRO[testTableIndex].permissions.edit, true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connectionId not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = ''; - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = ''; + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connection id is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = faker.string.uuid(); - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 400); - const { message } = JSON.parse(getTablesResponse.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = faker.string.uuid(); + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 400); + const { message } = JSON.parse(getTablesResponse.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return rows of selected table without search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return rows of selected table with search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createTableSettingsResponse.status, 201); - - const searchedDescription = '25'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const searchedDescription = '25'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=1, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Content-Type', 'application/json') - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=3, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 3); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 3); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - // t.is(getTableRowsRO.pagination.total, 42); - // t.is(getTableRowsRO.pagination.lastPage, 2); - // t.is(getTableRowsRO.pagination.perPage, 2); - // t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + // t.is(getTableRowsRO.pagination.total, 42); + // t.is(getTableRowsRO.pagination.lastPage, 2); + // t.is(getTableRowsRO.pagination.perPage, 2); + // t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - // t.is(getTableRowsRO.pagination.total, 42); - // t.is(getTableRowsRO.pagination.lastPage, 2); - // t.is(getTableRowsRO.pagination.perPage, 2); - // t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + // t.is(getTableRowsRO.pagination.total, 42); + // t.is(getTableRowsRO.pagination.lastPage, 2); + // t.is(getTableRowsRO.pagination.perPage, 2); + // t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by DESC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - t.is(getTableRowsRO.rows[41].id, 1); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + t.is(getTableRowsRO.rows[41].id, 1); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by ASC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - t.is(getTableRowsRO.rows[41].id, 42); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + t.is(getTableRowsRO.rows[41].id, 42); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and with pagination and with sorting + `${currentTest} without search and with pagination and with sorting should return all found rows with sorting ports by DESC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 39); - t.is(getTableRowsRO.rows[1].id, 38); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 39); + t.is(getTableRowsRO.rows[1].id, 38); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '45'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '45'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=10 and DESC sorting and filtering'`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[2].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 10); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[2].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 10); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and with multi filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - createConnectionRO.id = ''; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + createConnectionRO.id = ''; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - createConnectionRO.id = faker.string.uuid(); - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 403); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + createConnectionRO.id = faker.string.uuid(); + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 403); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 400); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 400); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = faker.lorem.words(1); - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTablesRO = JSON.parse(getTableRowsResponse.text); - t.is(getTablesRO.rows.length, 2); - t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTablesRO, 'pagination'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = faker.lorem.words(1); + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTablesRO = JSON.parse(getTableRowsResponse.text); + t.is(getTablesRO.rows.length, 2); + t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTablesRO, 'pagination'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 200); - const getTableStructureRO = JSON.parse(getTableStructure.text); - - t.is(typeof getTableStructureRO, 'object'); - t.is(typeof getTableStructureRO.structure, 'object'); - t.is(getTableStructureRO.structure.length, 5); - - for (const element of getTableStructureRO.structure) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'column_default'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - t.is(Object.hasOwn(element, 'isExcluded'), true); - t.is(Object.hasOwn(element, 'isSearched'), true); - } - - t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); - - for (const element of getTableStructureRO.primaryColumns) { - t.is(Object.hasOwn(element, 'column_name'), true); - // t.is(element.hasOwnProperty('data_type'), true); - } - - for (const element of getTableStructureRO.foreignKeys) { - t.is(Object.hasOwn(element, 'referenced_column_name'), true); - t.is(Object.hasOwn(element, 'referenced_table_name'), true); - t.is(Object.hasOwn(element, 'constraint_name'), true); - t.is(Object.hasOwn(element, 'column_name'), true); - } + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 200); + const getTableStructureRO = JSON.parse(getTableStructure.text); + + t.is(typeof getTableStructureRO, 'object'); + t.is(typeof getTableStructureRO.structure, 'object'); + t.is(getTableStructureRO.structure.length, 5); + + for (const element of getTableStructureRO.structure) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'column_default'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + t.is(Object.hasOwn(element, 'isExcluded'), true); + t.is(Object.hasOwn(element, 'isSearched'), true); + } + + t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); + + for (const element of getTableStructureRO.primaryColumns) { + t.is(Object.hasOwn(element, 'column_name'), true); + // t.is(element.hasOwnProperty('data_type'), true); + } + + for (const element of getTableStructureRO.foreignKeys) { + t.is(Object.hasOwn(element, 'referenced_column_name'), true); + t.is(Object.hasOwn(element, 'referenced_table_name'), true); + t.is(Object.hasOwn(element, 'constraint_name'), true); + t.is(Object.hasOwn(element, 'column_name'), true); + } }); test.serial(`${currentTest} should throw an exception whe connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 404); }); test.serial(`${currentTest} should throw an exception whe connection id passed in request id incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = faker.string.uuid(); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 403); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = faker.string.uuid(); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 403); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest}should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = faker.lorem.words(1); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = faker.lorem.words(1); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should add row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 43, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addRowInTableRO = JSON.parse(addRowInTableResponse.text); - t.is(addRowInTableResponse.status, 201); - - t.is(Object.hasOwn(addRowInTableRO, 'row'), true); - t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); - t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 43); - t.is(rows[42][testTableColumnName], row[testTableColumnName]); - t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); - t.is(rows[42].id, rows[41].id + 1); - - // check that rows adding was logged - - const getLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getLogsResponse.status, 200); - const getLogsRO = JSON.parse(getLogsResponse.text); - t.is(Object.hasOwn(getLogsRO, 'logs'), true); - t.is(Object.hasOwn(getLogsRO, 'pagination'), true); - t.is(getLogsRO.logs.length > 0, true); - const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); - t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); - t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, String(43)); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 43, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addRowInTableRO = JSON.parse(addRowInTableResponse.text); + t.is(addRowInTableResponse.status, 201); + + t.is(Object.hasOwn(addRowInTableRO, 'row'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 43); + t.is(rows[42][testTableColumnName], row[testTableColumnName]); + t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); + t.is(rows[42].id, rows[41].id + 1); + + // check that rows adding was logged + + const getLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getLogsResponse.status, 200); + const getLogsRO = JSON.parse(getLogsResponse.text); + t.is(Object.hasOwn(getLogsRO, 'logs'), true); + t.is(Object.hasOwn(getLogsRO, 'pagination'), true); + t.is(getLogsRO.logs.length > 0, true); + const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); + t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); + t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, String(43)); }); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const fakeConnectionId = ''; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 404); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const fakeConnectionId = ''; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 404); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when row is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.PARAMETER_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.PARAMETER_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); currentTest = 'PUT /table/row/:slug'; test.serial(`${currentTest} should update row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 200); - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); - t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was updated - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - const updateRowIndex = rows.map((row) => row.id).indexOf(1); - t.is(rows.length, 42); - t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); - t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 200); + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); + t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was updated + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + const updateRowIndex = rows.map((row) => row.id).indexOf(1); + t.is(rows.length, 42); + t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); + t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = ''; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = ''; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 404); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 403); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 403); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 41); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, true); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 41); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, true); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 404); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 404); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = faker.string.uuid(); - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 403); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = faker.string.uuid(); + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 403); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - t.is(deleteRowInTableResponse.status, 400); - t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + t.is(deleteRowInTableResponse.status, 400); + t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} found row`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 200); - const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); - t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); - t.is(typeof foundRowInTableRO.row, 'object'); - t.is(typeof foundRowInTableRO.structure, 'object'); - t.is(typeof foundRowInTableRO.primaryColumns, 'object'); - t.is(typeof foundRowInTableRO.readonly_fields, 'object'); - t.is(typeof foundRowInTableRO.foreignKeys, 'object'); - t.is(foundRowInTableRO.row.id, 1); - t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); - t.is(Object.keys(foundRowInTableRO.row).length, 5); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 200); + const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); + t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); + t.is(typeof foundRowInTableRO.row, 'object'); + t.is(typeof foundRowInTableRO.structure, 'object'); + t.is(typeof foundRowInTableRO.primaryColumns, 'object'); + t.is(typeof foundRowInTableRO.readonly_fields, 'object'); + t.is(typeof foundRowInTableRO.foreignKeys, 'object'); + t.is(foundRowInTableRO.row.id, 1); + t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); + t.is(Object.keys(foundRowInTableRO.row).length, 5); }); test.serial(`${currentTest} should throw an exception, when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const idForSearch = 1; - createConnectionRO.id = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const idForSearch = 1; + createConnectionRO.id = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 404); }); test.serial( - `${currentTest} should throw an exception, when connection id passed in request is incorrect`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - createConnectionRO.id = faker.string.uuid(); - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 403); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - }, + `${currentTest} should throw an exception, when connection id passed in request is incorrect`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + createConnectionRO.id = faker.string.uuid(); + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 403); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + }, ); test.serial(`${currentTest} should throw an exception, when tableName in not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception, when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception, when primary key is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1000000; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1000000; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/delete/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const primaryKeysForDeletion: Array> = [ - { - id: 1, - }, - { - id: 10, - }, - { - id: 32, - }, - ]; - const deleteRowsInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) - .send(primaryKeysForDeletion) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowsInTableResponse.status, 200); - const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - // check that lines was deleted - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); - - for (const key of primaryKeysForDeletion) { - t.is( - rows.findIndex((row) => row.id === key.id), - -1, - ); - } - - // check that table deletaion was logged - const tableLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(tableLogsResponse.status, 200); - - const tableLogsRO = JSON.parse(tableLogsResponse.text); - t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); - const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); - for (const key of primaryKeysForDeletion) { - t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); - } + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const primaryKeysForDeletion: Array> = [ + { + id: 1, + }, + { + id: 10, + }, + { + id: 32, + }, + ]; + const deleteRowsInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) + .send(primaryKeysForDeletion) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowsInTableResponse.status, 200); + const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + // check that lines was deleted + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); + + for (const key of primaryKeysForDeletion) { + t.is( + rows.findIndex((row) => row.id === key.id), + -1, + ); + } + + // check that table deletaion was logged + const tableLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(tableLogsResponse.status, 200); + + const tableLogsRO = JSON.parse(tableLogsResponse.text); + t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); + const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); + for (const key of primaryKeysForDeletion) { + t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); + } }); test.serial(`${currentTest} should test connection and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const testConnectionResponse = await request(app.getHttpServer()) - .post('/connection/test/') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse.status, 201); - const { message } = JSON.parse(testConnectionResponse.text); - t.is(message, 'Successfully connected'); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const testConnectionResponse = await request(app.getHttpServer()) + .post('/connection/test/') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse.status, 201); + const { message } = JSON.parse(testConnectionResponse.text); + t.is(message, 'Successfully connected'); }); diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-table-postgres-encrypted-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-table-postgres-encrypted-e2e.test.ts index df67df64b..ec50afc40 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-table-postgres-encrypted-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-table-postgres-encrypted-e2e.test.ts @@ -18,7 +18,10 @@ import { MockFactory } from '../../mock.factory.js'; import { createTestTable } from '../../utils/create-test-table.js'; import { dropTestTables } from '../../utils/drop-test-tables.js'; import { getTestData } from '../../utils/get-test-data.js'; -import { registerUserAndReturnUserInfo, createInitialTestUser } from '../../utils/register-user-and-return-user-info.js'; +import { + registerUserAndReturnUserInfo, + createInitialTestUser, +} from '../../utils/register-user-and-return-user-info.js'; import { TestUtils } from '../../utils/test.utils.js'; import { setSaasEnvVariable } from '../../utils/set-saas-env-variable.js'; import { ValidationException } from '../../../src/exceptions/custom-exceptions/validation-exception.js'; @@ -34,3718 +37,3718 @@ let currentTest; const masterPwd = faker.internet.password(); test.before(async () => { - setSaasEnvVariable(); - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - await createInitialTestUser(app); - app.getHttpServer().listen(0); + setSaasEnvVariable(); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + await createInitialTestUser(app); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - await dropTestTables(testTables, connectionToTestDB); - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + await dropTestTables(testTables, connectionToTestDB); + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /connection/tables/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 200); - const getTablesRO = JSON.parse(getTablesResponse.text); - - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.length > 0, true); - - const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); - - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); - t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); - t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); - t.is(getTablesRO[testTableIndex].table, testTableName); - t.is(getTablesRO[testTableIndex].permissions.visibility, true); - t.is(getTablesRO[testTableIndex].permissions.readonly, false); - t.is(getTablesRO[testTableIndex].permissions.add, true); - t.is(getTablesRO[testTableIndex].permissions.delete, true); - t.is(getTablesRO[testTableIndex].permissions.edit, true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 200); + const getTablesRO = JSON.parse(getTablesResponse.text); + + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.length > 0, true); + + const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); + + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); + t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); + t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); + t.is(getTablesRO[testTableIndex].table, testTableName); + t.is(getTablesRO[testTableIndex].permissions.visibility, true); + t.is(getTablesRO[testTableIndex].permissions.readonly, false); + t.is(getTablesRO[testTableIndex].permissions.add, true); + t.is(getTablesRO[testTableIndex].permissions.delete, true); + t.is(getTablesRO[testTableIndex].permissions.edit, true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connectionId not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = ''; - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = ''; + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when master password is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const incorrectMasterPwd = faker.internet.password(); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('masterpwd', incorrectMasterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 400); - const getTablesRO = JSON.parse(getTablesResponse.text); - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.message, Messages.MASTER_PASSWORD_INCORRECT); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const incorrectMasterPwd = faker.internet.password(); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('masterpwd', incorrectMasterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 400); + const getTablesRO = JSON.parse(getTablesResponse.text); + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.message, Messages.MASTER_PASSWORD_INCORRECT); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connection id is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = faker.string.uuid(); - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 400); - const { message } = JSON.parse(getTablesResponse.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = faker.string.uuid(); + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 400); + const { message } = JSON.parse(getTablesResponse.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return rows of selected table without search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return rows of selected table with search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createTableSettingsResponse.status, 201); - - const searchedDescription = '5'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const searchedDescription = '5'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=1, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=3, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 3); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 3); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by DESC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - t.is(getTableRowsRO.rows[41].id, 1); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + t.is(getTableRowsRO.rows[41].id, 1); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by ASC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - t.is(getTableRowsRO.rows[41].id, 42); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + t.is(getTableRowsRO.rows[41].id, 42); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and with pagination and with sorting + `${currentTest} without search and with pagination and with sorting should return all found rows with sorting ports by DESC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 39); - t.is(getTableRowsRO.rows[1].id, 38); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 39); + t.is(getTableRowsRO.rows[1].id, 38); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '45'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '45'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=10 and DESC sorting and filtering'`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[2].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 10); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[2].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 10); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and with multi filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - createConnectionRO.id = ''; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + createConnectionRO.id = ''; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - createConnectionRO.id = faker.string.uuid(); - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 403); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + createConnectionRO.id = faker.string.uuid(); + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 403); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 400); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 400); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = faker.lorem.words(1); - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTablesRO = JSON.parse(getTableRowsResponse.text); - t.is(getTablesRO.rows.length, 2); - t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTablesRO, 'pagination'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = faker.lorem.words(1); + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTablesRO = JSON.parse(getTableRowsResponse.text); + t.is(getTablesRO.rows.length, 2); + t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTablesRO, 'pagination'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 200); - const getTableStructureRO = JSON.parse(getTableStructure.text); - - t.is(typeof getTableStructureRO, 'object'); - t.is(typeof getTableStructureRO.structure, 'object'); - t.is(getTableStructureRO.structure.length, 5); - - for (const element of getTableStructureRO.structure) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'column_default'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - t.is(Object.hasOwn(element, 'isExcluded'), true); - t.is(Object.hasOwn(element, 'isSearched'), true); - } - - t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); - - for (const element of getTableStructureRO.primaryColumns) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - } - - for (const element of getTableStructureRO.foreignKeys) { - t.is(Object.hasOwn(element, 'referenced_column_name'), true); - t.is(Object.hasOwn(element, 'referenced_table_name'), true); - t.is(Object.hasOwn(element, 'constraint_name'), true); - t.is(Object.hasOwn(element, 'column_name'), true); - } + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 200); + const getTableStructureRO = JSON.parse(getTableStructure.text); + + t.is(typeof getTableStructureRO, 'object'); + t.is(typeof getTableStructureRO.structure, 'object'); + t.is(getTableStructureRO.structure.length, 5); + + for (const element of getTableStructureRO.structure) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'column_default'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + t.is(Object.hasOwn(element, 'isExcluded'), true); + t.is(Object.hasOwn(element, 'isSearched'), true); + } + + t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); + + for (const element of getTableStructureRO.primaryColumns) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + } + + for (const element of getTableStructureRO.foreignKeys) { + t.is(Object.hasOwn(element, 'referenced_column_name'), true); + t.is(Object.hasOwn(element, 'referenced_table_name'), true); + t.is(Object.hasOwn(element, 'constraint_name'), true); + t.is(Object.hasOwn(element, 'column_name'), true); + } }); test.serial(`${currentTest} should throw an exception whe connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 404); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 404); }); test.serial(`${currentTest} should throw an exception whe connection id passed in request id incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = faker.string.uuid(); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 403); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = faker.string.uuid(); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 403); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest}should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should add row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addRowInTableRO = JSON.parse(addRowInTableResponse.text); - t.is(addRowInTableResponse.status, 201); - - t.is(Object.hasOwn(addRowInTableRO, 'row'), true); - t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); - t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 43); - t.is(rows[42][testTableColumnName], row[testTableColumnName]); - t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); - t.is(rows[42].id, rows[41].id + 1); - - // check that rows adding was logged - - const getLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getLogsResponse.status, 200); - const getLogsRO = JSON.parse(getLogsResponse.text); - t.is(Object.hasOwn(getLogsRO, 'logs'), true); - t.is(Object.hasOwn(getLogsRO, 'pagination'), true); - t.is(getLogsRO.logs.length > 0, true); - const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); - t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); - t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, 43); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addRowInTableRO = JSON.parse(addRowInTableResponse.text); + t.is(addRowInTableResponse.status, 201); + + t.is(Object.hasOwn(addRowInTableRO, 'row'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 43); + t.is(rows[42][testTableColumnName], row[testTableColumnName]); + t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); + t.is(rows[42].id, rows[41].id + 1); + + // check that rows adding was logged + + const getLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getLogsResponse.status, 200); + const getLogsRO = JSON.parse(getLogsResponse.text); + t.is(Object.hasOwn(getLogsRO, 'logs'), true); + t.is(Object.hasOwn(getLogsRO, 'pagination'), true); + t.is(getLogsRO.logs.length > 0, true); + const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); + t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); + t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, 43); }); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const fakeConnectionId = ''; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 404); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const fakeConnectionId = ''; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 404); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when row is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.PARAMETER_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.PARAMETER_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); currentTest = 'PUT /table/row/:slug'; test.serial(`${currentTest} should update row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 200); - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); - t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was updated - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - const updateRowIndex = rows.map((row) => row.id).indexOf(1); - t.is(rows.length, 42); - t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); - t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 200); + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); + t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was updated + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + const updateRowIndex = rows.map((row) => row.id).indexOf(1); + t.is(rows.length, 42); + t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); + t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = ''; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = ''; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 404); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 403); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 403); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 41); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, true); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 41); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, true); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 404); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 404); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = faker.string.uuid(); - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 403); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = faker.string.uuid(); + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 403); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - t.is(deleteRowInTableResponse.status, 400); - t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + t.is(deleteRowInTableResponse.status, 400); + t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} found row`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 200); - const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); - t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); - t.is(typeof foundRowInTableRO.row, 'object'); - t.is(typeof foundRowInTableRO.structure, 'object'); - t.is(typeof foundRowInTableRO.primaryColumns, 'object'); - t.is(typeof foundRowInTableRO.readonly_fields, 'object'); - t.is(typeof foundRowInTableRO.foreignKeys, 'object'); - t.is(foundRowInTableRO.row.id, 1); - t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); - t.is(Object.keys(foundRowInTableRO.row).length, 5); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 200); + const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); + t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); + t.is(typeof foundRowInTableRO.row, 'object'); + t.is(typeof foundRowInTableRO.structure, 'object'); + t.is(typeof foundRowInTableRO.primaryColumns, 'object'); + t.is(typeof foundRowInTableRO.readonly_fields, 'object'); + t.is(typeof foundRowInTableRO.foreignKeys, 'object'); + t.is(foundRowInTableRO.row.id, 1); + t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); + t.is(Object.keys(foundRowInTableRO.row).length, 5); }); test.serial(`${currentTest} should throw an exception, when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const idForSearch = 1; - createConnectionRO.id = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const idForSearch = 1; + createConnectionRO.id = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 404); }); test.serial( - `${currentTest} should throw an exception, when connection id passed in request is incorrect`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - createConnectionRO.id = faker.string.uuid(); - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 403); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - }, + `${currentTest} should throw an exception, when connection id passed in request is incorrect`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + createConnectionRO.id = faker.string.uuid(); + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 403); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + }, ); test.serial(`${currentTest} should throw an exception, when tableName in not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception, when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception, when primary key is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(foundRowInTableResponse.status, 400); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(foundRowInTableResponse.status, 400); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1000000; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1000000; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-table-postgres-schema-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-table-postgres-schema-e2e.test.ts index b79092fb4..01f8f7992 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-table-postgres-schema-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-table-postgres-schema-e2e.test.ts @@ -21,7 +21,10 @@ import { MockFactory } from '../../mock.factory.js'; import { createTestPostgresTableWithSchema } from '../../utils/create-test-table.js'; import { dropTestTables } from '../../utils/drop-test-tables.js'; import { getTestData } from '../../utils/get-test-data.js'; -import { registerUserAndReturnUserInfo, createInitialTestUser } from '../../utils/register-user-and-return-user-info.js'; +import { + registerUserAndReturnUserInfo, + createInitialTestUser, +} from '../../utils/register-user-and-return-user-info.js'; import { setSaasEnvVariable } from '../../utils/set-saas-env-variable.js'; import { TestUtils } from '../../utils/test.utils.js'; diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-table-redis-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-table-redis-e2e.test.ts index 3df567d5e..549fb0359 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-table-redis-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-table-redis-e2e.test.ts @@ -23,7 +23,10 @@ import { DatabaseService } from '../../../src/shared/database/database.service.j import { MockFactory } from '../../mock.factory.js'; import { createTestTable } from '../../utils/create-test-table.js'; import { getTestData } from '../../utils/get-test-data.js'; -import { registerUserAndReturnUserInfo, createInitialTestUser } from '../../utils/register-user-and-return-user-info.js'; +import { + registerUserAndReturnUserInfo, + createInitialTestUser, +} from '../../utils/register-user-and-return-user-info.js'; import { TestUtils } from '../../utils/test.utils.js'; import { setSaasEnvVariable } from '../../utils/set-saas-env-variable.js'; import os from 'node:os'; @@ -39,3969 +42,3969 @@ const testTables: Array = []; let currentTest; test.before(async () => { - setSaasEnvVariable(); - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication() as any; - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - await createInitialTestUser(app); - app.getHttpServer().listen(0); + setSaasEnvVariable(); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication() as any; + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + await createInitialTestUser(app); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /connection/tables/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTablesRO = JSON.parse(getTablesResponse.text); - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.length > 0, true); - - const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); - - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); - t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); - t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); - t.is(getTablesRO[testTableIndex].table, testTableName); - t.is(getTablesRO[testTableIndex].permissions.visibility, true); - t.is(getTablesRO[testTableIndex].permissions.readonly, false); - t.is(getTablesRO[testTableIndex].permissions.add, true); - t.is(getTablesRO[testTableIndex].permissions.delete, true); - t.is(getTablesRO[testTableIndex].permissions.edit, true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTablesRO = JSON.parse(getTablesResponse.text); + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.length > 0, true); + + const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); + + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); + t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); + t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); + t.is(getTablesRO[testTableIndex].table, testTableName); + t.is(getTablesRO[testTableIndex].permissions.visibility, true); + t.is(getTablesRO[testTableIndex].permissions.readonly, false); + t.is(getTablesRO[testTableIndex].permissions.add, true); + t.is(getTablesRO[testTableIndex].permissions.delete, true); + t.is(getTablesRO[testTableIndex].permissions.edit, true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connectionId not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = ''; - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = ''; + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connection id is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = faker.string.uuid(); - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 400); - const { message } = JSON.parse(getTablesResponse.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = faker.string.uuid(); + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 400); + const { message } = JSON.parse(getTablesResponse.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return rows of selected table without search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(Object.hasOwn(getTableRowsRO, 'large_dataset'), true); - t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'key'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(Object.hasOwn(getTableRowsRO, 'large_dataset'), true); + t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'key'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return rows of selected table with search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['key'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createTableSettingsResponse.status, 201); - - const searchedDescription = insertedSearchedIds.find((id) => id.number === 0).id; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - console.log('🚀 ~ getTableRowsRO:', getTableRowsRO); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0].key, searchedDescription); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['key'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const searchedDescription = insertedSearchedIds.find((id) => id.number === 0).id; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + console.log('🚀 ~ getTableRowsRO:', getTableRowsRO); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0].key, searchedDescription); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=1, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['key'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Content-Type', 'application/json') - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'key'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'key'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['key'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'key'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'key'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=3, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['key'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'key'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'key'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 3); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['key'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'key'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'key'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 3); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - console.log('🚀 ~ getTableRowsRO:', getTableRowsRO); - - t.is(getTableRowsResponse.status, 200); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'key'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + console.log('🚀 ~ getTableRowsRO:', getTableRowsRO); + + t.is(getTableRowsResponse.status, 200); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'key'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'key'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'key'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by DESC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.DESC, - 'key', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - // t.is(getTableRowsRO.rows[0].key, 42); - // t.is(getTableRowsRO.rows[1].key, 41); - // t.is(getTableRowsRO.rows[41].id, 1); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.DESC, + 'key', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + // t.is(getTableRowsRO.rows[0].key, 42); + // t.is(getTableRowsRO.rows[1].key, 41); + // t.is(getTableRowsRO.rows[41].id, 1); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting age by ASC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.ASC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - // check that rows are sorted by age in ASC order - for (let i = 1; i < getTableRowsRO.rows.length; i++) { - const currentAge = getTableRowsRO.rows[i].age; - const previousAge = getTableRowsRO.rows[i - 1].age; - t.is(currentAge >= previousAge, true); - } - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.ASC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + // check that rows are sorted by age in ASC order + for (let i = 1; i < getTableRowsRO.rows.length; i++) { + const currentAge = getTableRowsRO.rows[i].age; + const previousAge = getTableRowsRO.rows[i - 1].age; + t.is(currentAge >= previousAge, true); + } + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and with pagination and with sorting + `${currentTest} without search and with pagination and with sorting should return all found rows with sorting ages by DESC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - const searchedLastId = insertedSearchedIds.find((id) => id.number === 37).id; - - const preSearchedLastId = insertedSearchedIds.find((id) => id.number === 21).id; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(getTableRowsRO.rows[1].key, preSearchedLastId); - t.is(getTableRowsRO.rows[0].key, searchedLastId); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + const searchedLastId = insertedSearchedIds.find((id) => id.number === 37).id; + + const preSearchedLastId = insertedSearchedIds.find((id) => id.number === 21).id; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(getTableRowsRO.rows[1].key, preSearchedLastId); + t.is(getTableRowsRO.rows[0].key, searchedLastId); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ages by ASC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'key', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - - // check that returned rows are sorted - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ages by ASC and with pagination page=1, perPage=2`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'key', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + + // check that returned rows are sorted + } catch (e) { + console.error(e); + throw e; + } + }, ); test.skip(`${currentTest} should return all found rows with sorting ages by DESC and with pagination page=2, perPage=3`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - console.log('🚀 ~ getTableRowsRO:', getTableRowsRO); - - console.log('🚀 ~ insertedSearchedIds:', insertedSearchedIds); - const searchedFirstId = insertedSearchedIds.find((id) => id.number === 37).id; - - const searchedSecondId = insertedSearchedIds.find((id) => id.number === 21).id; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(getTableRowsRO.rows[0].key, searchedFirstId); - t.is(getTableRowsRO.rows[1].key, searchedSecondId); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + console.log('🚀 ~ getTableRowsRO:', getTableRowsRO); + + console.log('🚀 ~ insertedSearchedIds:', insertedSearchedIds); + const searchedFirstId = insertedSearchedIds.find((id) => id.number === 37).id; + + const searchedSecondId = insertedSearchedIds.find((id) => id.number === 21).id; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(getTableRowsRO.rows[0].key, searchedFirstId); + t.is(getTableRowsRO.rows[1].key, searchedSecondId); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - console.log('🚀 ~ getTableRowsRO:', getTableRowsRO); - - console.log('🚀 ~ insertedSearchedIds:', insertedSearchedIds); - const searchedFirstId = insertedSearchedIds.find((id) => id.number === 37).id; - - const searchedSecondId = insertedSearchedIds.find((id) => id.number === 21).id; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(getTableRowsRO.rows[0].key, searchedFirstId); - t.is(getTableRowsRO.rows[1].key, searchedSecondId); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + console.log('🚀 ~ getTableRowsRO:', getTableRowsRO); + + console.log('🚀 ~ insertedSearchedIds:', insertedSearchedIds); + const searchedFirstId = insertedSearchedIds.find((id) => id.number === 37).id; + + const searchedSecondId = insertedSearchedIds.find((id) => id.number === 21).id; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(getTableRowsRO.rows[0].key, searchedFirstId); + t.is(getTableRowsRO.rows[1].key, searchedSecondId); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - const searchedFirstId = insertedSearchedIds.find((id) => id.number === 0).id; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0].key, searchedFirstId); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + const searchedFirstId = insertedSearchedIds.find((id) => id.number === 0).id; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0].key, searchedFirstId); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const searchedFirstId = insertedSearchedIds.find((id) => id.number === 0).id; - const searchedSecondId = insertedSearchedIds.find((id) => id.number === 21).id; - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0].key, searchedFirstId); - t.is(getTableRowsRO.rows[1].key, searchedSecondId); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const searchedFirstId = insertedSearchedIds.find((id) => id.number === 0).id; + const searchedSecondId = insertedSearchedIds.find((id) => id.number === 21).id; + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0].key, searchedFirstId); + t.is(getTableRowsRO.rows[1].key, searchedSecondId); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'key', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - const searchedFirstId = insertedSearchedIds.find((id) => id.number === 37).id; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0].key, searchedFirstId); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'key', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + const searchedFirstId = insertedSearchedIds.find((id) => id.number === 37).id; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0].key, searchedFirstId); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); // todo: rework for other tables after removing old endpoint test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and filtering in body`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'key', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'age'; - const fieldvalue = 18; - - const filters = { - [fieldname]: { lt: fieldvalue }, - }; - - const getTableRowsResponse = await request(app.getHttpServer()) - .post( - `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .send({ filters }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - - const foundId = insertedSearchedIds.find((id) => id.number === 0).id; - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].key, foundId); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'key', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'age'; + const fieldvalue = 18; + + const filters = { + [fieldname]: { lt: fieldvalue }, + }; + + const getTableRowsResponse = await request(app.getHttpServer()) + .post( + `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .send({ filters }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + + const foundId = insertedSearchedIds.find((id) => id.number === 0).id; + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].key, foundId); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=10 and DESC sorting and filtering'`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'key', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'age'; - const fieldvalue = 18; - - const filters = { - [fieldname]: { lt: fieldvalue }, - }; - - const getTableRowsResponse = await request(app.getHttpServer()) - .post( - `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10`, - ) - .send({ filters }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 201); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - - const foundId = insertedSearchedIds.find((id) => id.number === 0).id; - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].key, foundId); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 10); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'key', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'age'; + const fieldvalue = 18; + + const filters = { + [fieldname]: { lt: fieldvalue }, + }; + + const getTableRowsResponse = await request(app.getHttpServer()) + .post( + `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10`, + ) + .send({ filters }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 201); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + + const foundId = insertedSearchedIds.find((id) => id.number === 0).id; + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].key, foundId); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 10); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and with multi filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'age'; - const fieldGtvalue = 14; - const fieldLtvalue = 95; - - const filters = { - [fieldname]: { lt: fieldLtvalue, gt: fieldGtvalue }, - }; - - const getTableRowsResponse = await request(app.getHttpServer()) - .post( - `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=3`, - ) - .send({ filters }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 201); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - console.log('🚀 ~ getTableRowsRO:', getTableRowsRO); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - - const findRowId = insertedSearchedIds.find((id) => id.number === 21).id; - - t.is(getTableRowsRO.rows[0].key, findRowId); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 3); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'age'; + const fieldGtvalue = 14; + const fieldLtvalue = 95; + + const filters = { + [fieldname]: { lt: fieldLtvalue, gt: fieldGtvalue }, + }; + + const getTableRowsResponse = await request(app.getHttpServer()) + .post( + `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=3`, + ) + .send({ filters }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 201); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + console.log('🚀 ~ getTableRowsRO:', getTableRowsRO); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + + const findRowId = insertedSearchedIds.find((id) => id.number === 21).id; + + t.is(getTableRowsRO.rows[0].key, findRowId); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 3); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'key', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'key'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - createConnectionRO.id = ''; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'key', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'key'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + createConnectionRO.id = ''; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'key', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'key'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - createConnectionRO.id = faker.string.uuid(); - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 403); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'key', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'key'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + createConnectionRO.id = faker.string.uuid(); + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 403); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'key', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'key'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 400); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'key', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'key'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 400); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = faker.lorem.words(1); - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTablesRO = JSON.parse(getTableRowsResponse.text); - t.is(getTablesRO.rows.length, 2); - t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTablesRO, 'pagination'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = faker.lorem.words(1); + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTablesRO = JSON.parse(getTableRowsResponse.text); + t.is(getTablesRO.rows.length, 2); + t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTablesRO, 'pagination'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 200); - const getTableStructureRO = JSON.parse(getTableStructure.text); - - t.is(typeof getTableStructureRO, 'object'); - t.is(typeof getTableStructureRO.structure, 'object'); - t.is(getTableStructureRO.structure.length, 6); - - for (const element of getTableStructureRO.structure) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'column_default'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - t.is(Object.hasOwn(element, 'isExcluded'), true); - t.is(Object.hasOwn(element, 'isSearched'), true); - } - - t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); - - for (const element of getTableStructureRO.primaryColumns) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - } - - for (const element of getTableStructureRO.foreignKeys) { - t.is(Object.hasOwn(element, 'referenced_column_name'), true); - t.is(Object.hasOwn(element, 'referenced_table_name'), true); - t.is(Object.hasOwn(element, 'constraint_name'), true); - t.is(Object.hasOwn(element, 'column_name'), true); - } + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 200); + const getTableStructureRO = JSON.parse(getTableStructure.text); + + t.is(typeof getTableStructureRO, 'object'); + t.is(typeof getTableStructureRO.structure, 'object'); + t.is(getTableStructureRO.structure.length, 6); + + for (const element of getTableStructureRO.structure) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'column_default'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + t.is(Object.hasOwn(element, 'isExcluded'), true); + t.is(Object.hasOwn(element, 'isSearched'), true); + } + + t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); + + for (const element of getTableStructureRO.primaryColumns) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + } + + for (const element of getTableStructureRO.foreignKeys) { + t.is(Object.hasOwn(element, 'referenced_column_name'), true); + t.is(Object.hasOwn(element, 'referenced_table_name'), true); + t.is(Object.hasOwn(element, 'constraint_name'), true); + t.is(Object.hasOwn(element, 'column_name'), true); + } }); test.serial(`${currentTest} should throw an exception whe connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 404); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 404); }); test.serial(`${currentTest} should throw an exception whe connection id passed in request id incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = faker.string.uuid(); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 403); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = faker.string.uuid(); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 403); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest}should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = faker.lorem.words(1); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = faker.lorem.words(1); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should add row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - key: `user_43`, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addRowInTableRO = JSON.parse(addRowInTableResponse.text); - t.is(addRowInTableResponse.status, 201); - - t.is(Object.hasOwn(addRowInTableRO, 'row'), true); - t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); - t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - console.log('🚀 ~ rows:', rows); - - const addedRowIndex = rows.findIndex((r) => r.key === row.key); - - t.is(rows.length, 43); - t.is(rows[addedRowIndex][testTableColumnName], row[testTableColumnName]); - t.is(rows[addedRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); - - // check that rows adding was logged - - const getLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getLogsResponse.status, 200); - const getLogsRO = JSON.parse(getLogsResponse.text); - t.is(Object.hasOwn(getLogsRO, 'logs'), true); - t.is(Object.hasOwn(getLogsRO, 'pagination'), true); - t.is(getLogsRO.logs.length > 0, true); - const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); - t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'key'), true); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + key: `user_43`, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addRowInTableRO = JSON.parse(addRowInTableResponse.text); + t.is(addRowInTableResponse.status, 201); + + t.is(Object.hasOwn(addRowInTableRO, 'row'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + console.log('🚀 ~ rows:', rows); + + const addedRowIndex = rows.findIndex((r) => r.key === row.key); + + t.is(rows.length, 43); + t.is(rows[addedRowIndex][testTableColumnName], row[testTableColumnName]); + t.is(rows[addedRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); + + // check that rows adding was logged + + const getLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getLogsResponse.status, 200); + const getLogsRO = JSON.parse(getLogsResponse.text); + t.is(Object.hasOwn(getLogsRO, 'logs'), true); + t.is(Object.hasOwn(getLogsRO, 'pagination'), true); + t.is(getLogsRO.logs.length > 0, true); + const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); + t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'key'), true); }); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - key: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const fakeConnectionId = ''; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 404); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + key: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const fakeConnectionId = ''; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 404); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - key: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + key: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when row is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.PARAMETER_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.PARAMETER_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - key: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.number.int({ min: 1, max: 10000 })}`; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + key: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.number.int({ min: 1, max: 10000 })}`; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); currentTest = 'PUT /table/row/:slug'; test.serial(`${currentTest} should update row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const foundIdForUpdate = insertedSearchedIds[0].id; - console.log('🚀 ~ foundIdForUpdate:', foundIdForUpdate); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=${foundIdForUpdate}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 200); - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - console.log('🚀 ~ updateRowInTableRO:', updateRowInTableRO); - - t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); - t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was updated - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - const updateRowIndex = rows.map((row) => row.key).indexOf(foundIdForUpdate); - t.is(rows.length, 42); - t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); - t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const foundIdForUpdate = insertedSearchedIds[0].id; + console.log('🚀 ~ foundIdForUpdate:', foundIdForUpdate); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=${foundIdForUpdate}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 200); + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + console.log('🚀 ~ updateRowInTableRO:', updateRowInTableRO); + + t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); + t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was updated + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + const updateRowIndex = rows.map((row) => row.key).indexOf(foundIdForUpdate); + t.is(rows.length, 42); + t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); + t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = ''; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = ''; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 404); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 403); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 403); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=&key=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=&key=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&key=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&key=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=100000000`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const responseObject = JSON.parse(updateRowInTableResponse.text); - t.is(responseObject.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=100000000`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const responseObject = JSON.parse(updateRowInTableResponse.text); + t.is(responseObject.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/update/:connectionId'; test.serial(`${currentTest} should update multiple rows and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const foundFirstIdForUpdate = insertedSearchedIds[0].id; - const foundSecondIdForUpdate = insertedSearchedIds[1].id; - const requestData = { - primaryKeys: [{ key: foundFirstIdForUpdate }, { key: foundSecondIdForUpdate }], - newValues: { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(requestData)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(updateRowInTableResponse.status, 200); - t.is(updateRowInTableRO.success, true); - - // check that the rows were updated - const firstRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=${foundFirstIdForUpdate}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const firstRow = JSON.parse(firstRowResponse.text); - t.is(firstRowResponse.status, 200); - t.is(firstRow.row[testTableColumnName], fakeName); - t.is(firstRow.row[testTableSecondColumnName], fakeMail); - - const secondRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=${foundSecondIdForUpdate}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const secondRow = JSON.parse(secondRowResponse.text); - t.is(secondRowResponse.status, 200); - t.is(secondRow.row[testTableColumnName], fakeName); - t.is(secondRow.row[testTableSecondColumnName], fakeMail); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const foundFirstIdForUpdate = insertedSearchedIds[0].id; + const foundSecondIdForUpdate = insertedSearchedIds[1].id; + const requestData = { + primaryKeys: [{ key: foundFirstIdForUpdate }, { key: foundSecondIdForUpdate }], + newValues: { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(requestData)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(updateRowInTableResponse.status, 200); + t.is(updateRowInTableRO.success, true); + + // check that the rows were updated + const firstRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=${foundFirstIdForUpdate}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const firstRow = JSON.parse(firstRowResponse.text); + t.is(firstRowResponse.status, 200); + t.is(firstRow.row[testTableColumnName], fakeName); + t.is(firstRow.row[testTableSecondColumnName], fakeMail); + + const secondRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=${foundSecondIdForUpdate}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const secondRow = JSON.parse(secondRowResponse.text); + t.is(secondRowResponse.status, 200); + t.is(secondRow.row[testTableColumnName], fakeName); + t.is(secondRow.row[testTableSecondColumnName], fakeMail); }); currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0].id; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 41); - const deletedRowIndex = rows.map((row: Record) => row.key).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, true); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0].id; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 41); + const deletedRowIndex = rows.map((row: Record) => row.key).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, true); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0].id; - const connectionId = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&key=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 404); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.key).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0].id; + const connectionId = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&key=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 404); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.key).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0].id; - const connectionId = faker.string.uuid(); - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&key=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 403); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.key).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0].id; + const connectionId = faker.string.uuid(); + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&key=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 403); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.key).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0].id; - const fakeTableName = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&key=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.key).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0].id; + const fakeTableName = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&key=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.key).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0].id; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&key=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.key).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0].id; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&key=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.key).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0].id; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.key).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0].id; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.key).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0].id; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.key).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0].id; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.key).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=100000`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - console.log('🚀 ~ deleteRowInTableRO:', deleteRowInTableRO); - t.is(deleteRowInTableResponse.status, 400); - t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=100000`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + console.log('🚀 ~ deleteRowInTableRO:', deleteRowInTableRO); + t.is(deleteRowInTableResponse.status, 400); + t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} found row`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = insertedSearchedIds[0].id; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 200); - const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); - t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); - t.is(typeof foundRowInTableRO.row, 'object'); - t.is(typeof foundRowInTableRO.structure, 'object'); - t.is(typeof foundRowInTableRO.primaryColumns, 'object'); - t.is(typeof foundRowInTableRO.readonly_fields, 'object'); - t.is(typeof foundRowInTableRO.foreignKeys, 'object'); - t.is(foundRowInTableRO.row.key, idForSearch); - t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); - t.is(Object.keys(foundRowInTableRO.row).length, 6); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = insertedSearchedIds[0].id; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 200); + const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); + t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); + t.is(typeof foundRowInTableRO.row, 'object'); + t.is(typeof foundRowInTableRO.structure, 'object'); + t.is(typeof foundRowInTableRO.primaryColumns, 'object'); + t.is(typeof foundRowInTableRO.readonly_fields, 'object'); + t.is(typeof foundRowInTableRO.foreignKeys, 'object'); + t.is(foundRowInTableRO.row.key, idForSearch); + t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); + t.is(Object.keys(foundRowInTableRO.row).length, 6); }); test.serial(`${currentTest} should throw an exception, when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const idForSearch = 1; - createConnectionRO.id = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const idForSearch = 1; + createConnectionRO.id = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 404); }); test.serial( - `${currentTest} should throw an exception, when connection id passed in request is incorrect`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - createConnectionRO.id = faker.string.uuid(); - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 403); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - }, + `${currentTest} should throw an exception, when connection id passed in request is incorrect`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + createConnectionRO.id = faker.string.uuid(); + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 403); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + }, ); test.serial(`${currentTest} should throw an exception, when tableName in not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&key=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&key=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception, when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&key=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&key=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception, when primary key is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = insertedSearchedIds[0].id; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = insertedSearchedIds[0].id; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = '6604197dab8d910eb77783f9'; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const findRowResponse = JSON.parse(foundRowInTableResponse.text); - t.is(findRowResponse.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = '6604197dab8d910eb77783f9'; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&key=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const findRowResponse = JSON.parse(foundRowInTableResponse.text); + t.is(findRowResponse.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/delete/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const primaryKeysForDeletion: Array> = [ - { - key: insertedSearchedIds[0].id, - }, - { - key: insertedSearchedIds[1].id, - }, - { - key: insertedSearchedIds[2].id, - }, - ]; - const deleteRowsInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) - .send(primaryKeysForDeletion) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowsInTableResponse.status, 200); - const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - // check that lines was deleted - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); - - for (const key of primaryKeysForDeletion) { - t.is( - rows.findIndex((row) => row.key === key.key), - -1, - ); - } - - // check that table deletaion was logged - const tableLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(tableLogsResponse.status, 200); - - const tableLogsRO = JSON.parse(tableLogsResponse.text); - t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); - const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); - for (const key of primaryKeysForDeletion) { - t.is(onlyDeleteLogs.findIndex((log) => log.received_data.key === key.key) >= 0, true); - } + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const primaryKeysForDeletion: Array> = [ + { + key: insertedSearchedIds[0].id, + }, + { + key: insertedSearchedIds[1].id, + }, + { + key: insertedSearchedIds[2].id, + }, + ]; + const deleteRowsInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) + .send(primaryKeysForDeletion) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowsInTableResponse.status, 200); + const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + // check that lines was deleted + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); + + for (const key of primaryKeysForDeletion) { + t.is( + rows.findIndex((row) => row.key === key.key), + -1, + ); + } + + // check that table deletaion was logged + const tableLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(tableLogsResponse.status, 200); + + const tableLogsRO = JSON.parse(tableLogsResponse.text); + t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); + const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); + for (const key of primaryKeysForDeletion) { + t.is(onlyDeleteLogs.findIndex((log) => log.received_data.key === key.key) >= 0, true); + } }); currentTest = 'DELETE /table/rows/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const primaryKeysForDeletion = [ - { - key: insertedSearchedIds[0].id, - }, - { - key: insertedSearchedIds[1].id, - }, - { - key: insertedSearchedIds[2].id, - }, - ]; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) - .send(primaryKeysForDeletion) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const _deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(getTableRowsResponse.status, 200); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 39); - for (const primaryKey of primaryKeysForDeletion) { - t.is( - rows.findIndex((row) => row.key === primaryKey.key), - -1, - ); - } + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const primaryKeysForDeletion = [ + { + key: insertedSearchedIds[0].id, + }, + { + key: insertedSearchedIds[1].id, + }, + { + key: insertedSearchedIds[2].id, + }, + ]; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) + .send(primaryKeysForDeletion) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const _deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(getTableRowsResponse.status, 200); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 39); + for (const primaryKey of primaryKeysForDeletion) { + t.is( + rows.findIndex((row) => row.key === primaryKey.key), + -1, + ); + } }); test.serial(`${currentTest} should test connection and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const testConnectionResponse = await request(app.getHttpServer()) - .post('/connection/test/') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse.status, 201); - const { message } = JSON.parse(testConnectionResponse.text); - t.is(message, 'Successfully connected'); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const testConnectionResponse = await request(app.getHttpServer()) + .post('/connection/test/') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse.status, 201); + const { message } = JSON.parse(testConnectionResponse.text); + t.is(message, 'Successfully connected'); }); currentTest = 'GET table/csv/:slug'; test.serial(`${currentTest} should return csv file with table data`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); }); test.serial( - `${currentTest} should return csv file with table data with search, with pagination, with sorting, + `${currentTest} should return csv file with table data with search, with pagination, with sorting, with search and pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'key', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post( - `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - }, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'key', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post( + `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + }, ); currentTest = 'POST /table/csv/import/:slug'; test.serial(`${currentTest} should import csv file with table data`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).redisConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'key', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post( - `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - const getTableCsvResponseText = JSON.parse(getTableCsvResponse.text); - console.log(getTableCsvResponseText); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - - function deleteIdColumnsInCSVFile(filePatch: string) { - // eslint-disable-next-line security/detect-non-literal-fs-filename - const fileContent = fs.readFileSync(filePatch).toString(); - const rows = fileContent.split('\n'); - const idColumnIndex = rows[0].split(',').indexOf('key'); - const newRows = rows.map((row) => { - const columns = row.split(','); - if (columns.length === 1) { - return row; - } - if (idColumnIndex >= 0) { - columns.splice(idColumnIndex, 1); - } - return columns.join(','); - }); - return newRows.join('\n'); - } - - const newFileContent = deleteIdColumnsInCSVFile(downloadedFilePatch); - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, newFileContent); - - const importCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) - .attach('file', downloadedFilePatch) - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - - t.is(importCsvResponse.status, 201); - - //checking that the lines was added - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(getTableRowsResponse.status, 200); - t.is(getTableRowsRO.rows.length, testEntitiesSeedsCount + 2); + const connectionToTestDB = getTestData(mockFactory).redisConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'key', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post( + `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + const getTableCsvResponseText = JSON.parse(getTableCsvResponse.text); + console.log(getTableCsvResponseText); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + + function deleteIdColumnsInCSVFile(filePatch: string) { + // eslint-disable-next-line security/detect-non-literal-fs-filename + const fileContent = fs.readFileSync(filePatch).toString(); + const rows = fileContent.split('\n'); + const idColumnIndex = rows[0].split(',').indexOf('key'); + const newRows = rows.map((row) => { + const columns = row.split(','); + if (columns.length === 1) { + return row; + } + if (idColumnIndex >= 0) { + columns.splice(idColumnIndex, 1); + } + return columns.join(','); + }); + return newRows.join('\n'); + } + + const newFileContent = deleteIdColumnsInCSVFile(downloadedFilePatch); + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, newFileContent); + + const importCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) + .attach('file', downloadedFilePatch) + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + + t.is(importCsvResponse.status, 201); + + //checking that the lines was added + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(getTableRowsResponse.status, 200); + t.is(getTableRowsRO.rows.length, testEntitiesSeedsCount + 2); }); diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-user-sign-in-audit.e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-user-sign-in-audit.e2e.test.ts index b8f9926bc..c2e043773 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-user-sign-in-audit.e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-user-sign-in-audit.e2e.test.ts @@ -12,7 +12,10 @@ import { ValidationException } from '../../../src/exceptions/custom-exceptions/v import { Messages } from '../../../src/exceptions/text/messages.js'; import { DatabaseModule } from '../../../src/shared/database/database.module.js'; import { DatabaseService } from '../../../src/shared/database/database.service.js'; -import { registerUserAndReturnUserInfo, createInitialTestUser } from '../../utils/register-user-and-return-user-info.js'; +import { + registerUserAndReturnUserInfo, + createInitialTestUser, +} from '../../utils/register-user-and-return-user-info.js'; import { TestUtils } from '../../utils/test.utils.js'; import { Cacher } from '../../../src/helpers/cache/cacher.js'; import { MockFactory } from '../../mock.factory.js'; @@ -28,433 +31,433 @@ let _testUtils: TestUtils; const _mockFactory = new MockFactory(); async function getCompanyIdByToken(app: INestApplication, token: string): Promise { - const getCompanyResult = await request(app.getHttpServer()) - .get('/company/my/full') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const companyInfo = JSON.parse(getCompanyResult.text); - return companyInfo.id; + const getCompanyResult = await request(app.getHttpServer()) + .get('/company/my/full') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const companyInfo = JSON.parse(getCompanyResult.text); + return companyInfo.id; } test.before(async () => { - setSaasEnvVariable(); - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - await createInitialTestUser(app); - app.getHttpServer().listen(0); + setSaasEnvVariable(); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + await createInitialTestUser(app); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /sign-in-audit/logs'; test.serial(`${currentTest} should return sign-in audit logs after successful login`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email, password } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Login again to create a sign-in audit record - const loginUserResult = await request(app.getHttpServer()) - .post('/user/login/') - .send({ email, password }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(loginUserResult.status, 201); - - // Get sign-in audit logs - const getAuditLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getAuditLogsResult.status, 200); - const auditLogsRO = JSON.parse(getAuditLogsResult.text); - - t.is(Object.hasOwn(auditLogsRO, 'logs'), true); - t.is(Object.hasOwn(auditLogsRO, 'pagination'), true); - t.true(auditLogsRO.logs.length >= 1); - - // Check that the log entry has expected structure - const logEntry = auditLogsRO.logs.find((log: any) => log.email === email.toLowerCase()); - t.truthy(logEntry); - t.is(logEntry.status, SignInStatusEnum.SUCCESS); - t.is(logEntry.signInMethod, SignInMethodEnum.EMAIL); - t.is(Object.hasOwn(logEntry, 'createdAt'), true); - t.is(Object.hasOwn(logEntry, 'ipAddress'), true); - } catch (err) { - console.error(err); - throw err; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email, password } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Login again to create a sign-in audit record + const loginUserResult = await request(app.getHttpServer()) + .post('/user/login/') + .send({ email, password }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(loginUserResult.status, 201); + + // Get sign-in audit logs + const getAuditLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getAuditLogsResult.status, 200); + const auditLogsRO = JSON.parse(getAuditLogsResult.text); + + t.is(Object.hasOwn(auditLogsRO, 'logs'), true); + t.is(Object.hasOwn(auditLogsRO, 'pagination'), true); + t.true(auditLogsRO.logs.length >= 1); + + // Check that the log entry has expected structure + const logEntry = auditLogsRO.logs.find((log: any) => log.email === email.toLowerCase()); + t.truthy(logEntry); + t.is(logEntry.status, SignInStatusEnum.SUCCESS); + t.is(logEntry.signInMethod, SignInMethodEnum.EMAIL); + t.is(Object.hasOwn(logEntry, 'createdAt'), true); + t.is(Object.hasOwn(logEntry, 'ipAddress'), true); + } catch (err) { + console.error(err); + throw err; + } }); test.serial(`${currentTest} should return sign-in audit logs with failed login attempt`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email, password } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Attempt login with wrong password to create a failed sign-in audit record - const wrongPassword = 'wrong_password_12345'; - const failedLoginResult = await request(app.getHttpServer()) - .post('/user/login/') - .send({ email, password: wrongPassword }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(failedLoginResult.status, 400); - - // Get sign-in audit logs - const getAuditLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getAuditLogsResult.status, 200); - const auditLogsRO = JSON.parse(getAuditLogsResult.text); - - t.is(Object.hasOwn(auditLogsRO, 'logs'), true); - t.true(auditLogsRO.logs.length >= 1); - - // Find the failed login entry - const failedLogEntry = auditLogsRO.logs.find( - (log: any) => log.email === email.toLowerCase() && log.status === SignInStatusEnum.FAILED, - ); - t.truthy(failedLogEntry); - t.is(failedLogEntry.signInMethod, SignInMethodEnum.EMAIL); - t.truthy(failedLogEntry.failureReason); - } catch (err) { - console.error(err); - throw err; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email, password } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Attempt login with wrong password to create a failed sign-in audit record + const wrongPassword = 'wrong_password_12345'; + const failedLoginResult = await request(app.getHttpServer()) + .post('/user/login/') + .send({ email, password: wrongPassword }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(failedLoginResult.status, 400); + + // Get sign-in audit logs + const getAuditLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getAuditLogsResult.status, 200); + const auditLogsRO = JSON.parse(getAuditLogsResult.text); + + t.is(Object.hasOwn(auditLogsRO, 'logs'), true); + t.true(auditLogsRO.logs.length >= 1); + + // Find the failed login entry + const failedLogEntry = auditLogsRO.logs.find( + (log: any) => log.email === email.toLowerCase() && log.status === SignInStatusEnum.FAILED, + ); + t.truthy(failedLogEntry); + t.is(failedLogEntry.signInMethod, SignInMethodEnum.EMAIL); + t.truthy(failedLogEntry.failureReason); + } catch (err) { + console.error(err); + throw err; + } }); test.serial(`${currentTest} should filter sign-in audit logs by status`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email, password } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Create a failed login attempt - const wrongPassword = 'wrong_password_12345'; - await request(app.getHttpServer()) - .post('/user/login/') - .send({ email, password: wrongPassword }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - // Create a successful login - await request(app.getHttpServer()) - .post('/user/login/') - .send({ email, password }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - // Get only failed sign-in audit logs - const getFailedLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}&status=${SignInStatusEnum.FAILED}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getFailedLogsResult.status, 200); - const failedLogsRO = JSON.parse(getFailedLogsResult.text); - - t.is(Object.hasOwn(failedLogsRO, 'logs'), true); - // All returned logs should have failed status - failedLogsRO.logs.forEach((log: any) => { - t.is(log.status, SignInStatusEnum.FAILED); - }); - - // Get only successful sign-in audit logs - const getSuccessLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}&status=${SignInStatusEnum.SUCCESS}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getSuccessLogsResult.status, 200); - const successLogsRO = JSON.parse(getSuccessLogsResult.text); - - t.is(Object.hasOwn(successLogsRO, 'logs'), true); - // All returned logs should have success status - successLogsRO.logs.forEach((log: any) => { - t.is(log.status, SignInStatusEnum.SUCCESS); - }); - } catch (err) { - console.error(err); - throw err; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email, password } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Create a failed login attempt + const wrongPassword = 'wrong_password_12345'; + await request(app.getHttpServer()) + .post('/user/login/') + .send({ email, password: wrongPassword }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + // Create a successful login + await request(app.getHttpServer()) + .post('/user/login/') + .send({ email, password }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + // Get only failed sign-in audit logs + const getFailedLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}&status=${SignInStatusEnum.FAILED}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getFailedLogsResult.status, 200); + const failedLogsRO = JSON.parse(getFailedLogsResult.text); + + t.is(Object.hasOwn(failedLogsRO, 'logs'), true); + // All returned logs should have failed status + failedLogsRO.logs.forEach((log: any) => { + t.is(log.status, SignInStatusEnum.FAILED); + }); + + // Get only successful sign-in audit logs + const getSuccessLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}&status=${SignInStatusEnum.SUCCESS}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getSuccessLogsResult.status, 200); + const successLogsRO = JSON.parse(getSuccessLogsResult.text); + + t.is(Object.hasOwn(successLogsRO, 'logs'), true); + // All returned logs should have success status + successLogsRO.logs.forEach((log: any) => { + t.is(log.status, SignInStatusEnum.SUCCESS); + }); + } catch (err) { + console.error(err); + throw err; + } }); test.serial(`${currentTest} should filter sign-in audit logs by email`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email, password } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Create a successful login - await request(app.getHttpServer()) - .post('/user/login/') - .send({ email, password }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - // Get sign-in audit logs filtered by email - const getAuditLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}&email=${email.toLowerCase()}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getAuditLogsResult.status, 200); - const auditLogsRO = JSON.parse(getAuditLogsResult.text); - - t.is(Object.hasOwn(auditLogsRO, 'logs'), true); - // All returned logs should have the searched email - auditLogsRO.logs.forEach((log: any) => { - t.is(log.email, email.toLowerCase()); - }); - } catch (err) { - console.error(err); - throw err; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email, password } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Create a successful login + await request(app.getHttpServer()) + .post('/user/login/') + .send({ email, password }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + // Get sign-in audit logs filtered by email + const getAuditLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}&email=${email.toLowerCase()}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getAuditLogsResult.status, 200); + const auditLogsRO = JSON.parse(getAuditLogsResult.text); + + t.is(Object.hasOwn(auditLogsRO, 'logs'), true); + // All returned logs should have the searched email + auditLogsRO.logs.forEach((log: any) => { + t.is(log.email, email.toLowerCase()); + }); + } catch (err) { + console.error(err); + throw err; + } }); test.serial(`${currentTest} should filter sign-in audit logs by sign-in method`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email, password } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Create a successful login - await request(app.getHttpServer()) - .post('/user/login/') - .send({ email, password }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - // Get sign-in audit logs filtered by email sign-in method - const getAuditLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}&signInMethod=${SignInMethodEnum.EMAIL}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getAuditLogsResult.status, 200); - const auditLogsRO = JSON.parse(getAuditLogsResult.text); - - t.is(Object.hasOwn(auditLogsRO, 'logs'), true); - // All returned logs should have email sign-in method - auditLogsRO.logs.forEach((log: any) => { - t.is(log.signInMethod, SignInMethodEnum.EMAIL); - }); - } catch (err) { - console.error(err); - throw err; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email, password } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Create a successful login + await request(app.getHttpServer()) + .post('/user/login/') + .send({ email, password }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + // Get sign-in audit logs filtered by email sign-in method + const getAuditLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}&signInMethod=${SignInMethodEnum.EMAIL}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getAuditLogsResult.status, 200); + const auditLogsRO = JSON.parse(getAuditLogsResult.text); + + t.is(Object.hasOwn(auditLogsRO, 'logs'), true); + // All returned logs should have email sign-in method + auditLogsRO.logs.forEach((log: any) => { + t.is(log.signInMethod, SignInMethodEnum.EMAIL); + }); + } catch (err) { + console.error(err); + throw err; + } }); test.serial(`${currentTest} should support pagination for sign-in audit logs`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email, password } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Create multiple login attempts - for (let i = 0; i < 5; i++) { - await request(app.getHttpServer()) - .post('/user/login/') - .send({ email, password }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - } - - // Get sign-in audit logs with pagination - const getAuditLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}&page=1&perPage=2`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getAuditLogsResult.status, 200); - const auditLogsRO = JSON.parse(getAuditLogsResult.text); - - t.is(Object.hasOwn(auditLogsRO, 'logs'), true); - t.is(Object.hasOwn(auditLogsRO, 'pagination'), true); - t.true(auditLogsRO.logs.length <= 2); - t.is(Object.hasOwn(auditLogsRO.pagination, 'total'), true); - t.is(Object.hasOwn(auditLogsRO.pagination, 'lastPage'), true); - t.is(Object.hasOwn(auditLogsRO.pagination, 'perPage'), true); - t.is(Object.hasOwn(auditLogsRO.pagination, 'currentPage'), true); - } catch (err) { - console.error(err); - throw err; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email, password } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Create multiple login attempts + for (let i = 0; i < 5; i++) { + await request(app.getHttpServer()) + .post('/user/login/') + .send({ email, password }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + } + + // Get sign-in audit logs with pagination + const getAuditLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}&page=1&perPage=2`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getAuditLogsResult.status, 200); + const auditLogsRO = JSON.parse(getAuditLogsResult.text); + + t.is(Object.hasOwn(auditLogsRO, 'logs'), true); + t.is(Object.hasOwn(auditLogsRO, 'pagination'), true); + t.true(auditLogsRO.logs.length <= 2); + t.is(Object.hasOwn(auditLogsRO.pagination, 'total'), true); + t.is(Object.hasOwn(auditLogsRO.pagination, 'lastPage'), true); + t.is(Object.hasOwn(auditLogsRO.pagination, 'perPage'), true); + t.is(Object.hasOwn(auditLogsRO.pagination, 'currentPage'), true); + } catch (err) { + console.error(err); + throw err; + } }); test.serial(`${currentTest} should return 400 for invalid status filter`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Get sign-in audit logs with invalid status - const getAuditLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}&status=invalid_status`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getAuditLogsResult.status, 400); - const errorRO = JSON.parse(getAuditLogsResult.text); - t.is(errorRO.message, Messages.INVALID_SIGN_IN_STATUS); - } catch (err) { - console.error(err); - throw err; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Get sign-in audit logs with invalid status + const getAuditLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}&status=invalid_status`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getAuditLogsResult.status, 400); + const errorRO = JSON.parse(getAuditLogsResult.text); + t.is(errorRO.message, Messages.INVALID_SIGN_IN_STATUS); + } catch (err) { + console.error(err); + throw err; + } }); test.serial(`${currentTest} should return 400 for invalid sign-in method filter`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Get sign-in audit logs with invalid sign-in method - const getAuditLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}&signInMethod=invalid_method`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getAuditLogsResult.status, 400); - const errorRO = JSON.parse(getAuditLogsResult.text); - t.is(errorRO.message, Messages.INVALID_SIGN_IN_METHOD); - } catch (err) { - console.error(err); - throw err; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Get sign-in audit logs with invalid sign-in method + const getAuditLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}&signInMethod=invalid_method`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getAuditLogsResult.status, 400); + const errorRO = JSON.parse(getAuditLogsResult.text); + t.is(errorRO.message, Messages.INVALID_SIGN_IN_METHOD); + } catch (err) { + console.error(err); + throw err; + } }); test.serial(`${currentTest} should filter sign-in audit logs by date range`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email, password } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Create a successful login - await request(app.getHttpServer()) - .post('/user/login/') - .send({ email, password }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const today = new Date(); - const yesterday = new Date(today); - yesterday.setDate(yesterday.getDate() - 1); - const tomorrow = new Date(today); - tomorrow.setDate(tomorrow.getDate() + 1); - - const dateFrom = yesterday.toISOString(); - const dateTo = tomorrow.toISOString(); - - // Get sign-in audit logs filtered by date range - const getAuditLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}&dateFrom=${dateFrom}&dateTo=${dateTo}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getAuditLogsResult.status, 200); - const auditLogsRO = JSON.parse(getAuditLogsResult.text); - - t.is(Object.hasOwn(auditLogsRO, 'logs'), true); - t.true(auditLogsRO.logs.length >= 1); - } catch (err) { - console.error(err); - throw err; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email, password } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Create a successful login + await request(app.getHttpServer()) + .post('/user/login/') + .send({ email, password }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const today = new Date(); + const yesterday = new Date(today); + yesterday.setDate(yesterday.getDate() - 1); + const tomorrow = new Date(today); + tomorrow.setDate(tomorrow.getDate() + 1); + + const dateFrom = yesterday.toISOString(); + const dateTo = tomorrow.toISOString(); + + // Get sign-in audit logs filtered by date range + const getAuditLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}&dateFrom=${dateFrom}&dateTo=${dateTo}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getAuditLogsResult.status, 200); + const auditLogsRO = JSON.parse(getAuditLogsResult.text); + + t.is(Object.hasOwn(auditLogsRO, 'logs'), true); + t.true(auditLogsRO.logs.length >= 1); + } catch (err) { + console.error(err); + throw err; + } }); test.serial( - `${currentTest} should not show audit for login attempt with non-existent user in company logs`, - async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Attempt login with non-existent email - const nonExistentEmail = `nonexistent_${faker.string.uuid()}@example.com`; - const failedLoginResult = await request(app.getHttpServer()) - .post('/user/login/') - .send({ email: nonExistentEmail, password: 'any_password', companyId }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(failedLoginResult.status, 404); - - // Get sign-in audit logs - const getAuditLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getAuditLogsResult.status, 200); - const auditLogsRO = JSON.parse(getAuditLogsResult.text); - - // Non-existent user login attempts should NOT be visible in company logs - // because the user doesn't belong to the company - const failedLogEntry = auditLogsRO.logs.find((log: any) => log.email === nonExistentEmail.toLowerCase()); - t.falsy(failedLogEntry); - } catch (err) { - console.error(err); - throw err; - } - }, + `${currentTest} should not show audit for login attempt with non-existent user in company logs`, + async (t) => { + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Attempt login with non-existent email + const nonExistentEmail = `nonexistent_${faker.string.uuid()}@example.com`; + const failedLoginResult = await request(app.getHttpServer()) + .post('/user/login/') + .send({ email: nonExistentEmail, password: 'any_password', companyId }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(failedLoginResult.status, 404); + + // Get sign-in audit logs + const getAuditLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getAuditLogsResult.status, 200); + const auditLogsRO = JSON.parse(getAuditLogsResult.text); + + // Non-existent user login attempts should NOT be visible in company logs + // because the user doesn't belong to the company + const failedLogEntry = auditLogsRO.logs.find((log: any) => log.email === nonExistentEmail.toLowerCase()); + t.falsy(failedLogEntry); + } catch (err) { + console.error(err); + throw err; + } + }, ); diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-user-table-different-group-connection-readonly-permissions-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-user-table-different-group-connection-readonly-permissions-e2e.test.ts index 301701c44..7c44f40e0 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-user-table-different-group-connection-readonly-permissions-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-user-table-different-group-connection-readonly-permissions-e2e.test.ts @@ -1,39 +1,38 @@ /* eslint-disable security/detect-object-injection */ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { faker } from "@faker-js/faker"; -import { INestApplication, ValidationPipe } from "@nestjs/common"; -import { Test } from "@nestjs/testing"; -import test from "ava"; -import { ValidationError } from "class-validator"; -import cookieParser from "cookie-parser"; -import request from "supertest"; -import { ApplicationModule } from "../../../src/app.module.js"; -import { WinstonLogger } from "../../../src/entities/logging/winston-logger.js"; +import { faker } from '@faker-js/faker'; +import { INestApplication, ValidationPipe } from '@nestjs/common'; +import { Test } from '@nestjs/testing'; +import test from 'ava'; +import { ValidationError } from 'class-validator'; +import cookieParser from 'cookie-parser'; +import request from 'supertest'; +import { ApplicationModule } from '../../../src/app.module.js'; +import { WinstonLogger } from '../../../src/entities/logging/winston-logger.js'; +import { AccessLevelEnum, QueryOrderingEnum } from '../../../src/enums/index.js'; +import { AllExceptionsFilter } from '../../../src/exceptions/all-exceptions.filter.js'; +import { ValidationException } from '../../../src/exceptions/custom-exceptions/validation-exception.js'; +import { Messages } from '../../../src/exceptions/text/messages.js'; +import { Cacher } from '../../../src/helpers/cache/cacher.js'; +import { Constants } from '../../../src/helpers/constants/constants.js'; +import { DatabaseModule } from '../../../src/shared/database/database.module.js'; +import { DatabaseService } from '../../../src/shared/database/database.service.js'; +import { MockFactory } from '../../mock.factory.js'; +import { compareTableWidgetsArrays } from '../../utils/compare-table-widgets-arrays.js'; import { - AccessLevelEnum, - QueryOrderingEnum, -} from "../../../src/enums/index.js"; -import { AllExceptionsFilter } from "../../../src/exceptions/all-exceptions.filter.js"; -import { ValidationException } from "../../../src/exceptions/custom-exceptions/validation-exception.js"; -import { Messages } from "../../../src/exceptions/text/messages.js"; -import { Cacher } from "../../../src/helpers/cache/cacher.js"; -import { Constants } from "../../../src/helpers/constants/constants.js"; -import { DatabaseModule } from "../../../src/shared/database/database.module.js"; -import { DatabaseService } from "../../../src/shared/database/database.service.js"; -import { MockFactory } from "../../mock.factory.js"; -import { compareTableWidgetsArrays } from "../../utils/compare-table-widgets-arrays.js"; -import { inviteUserInCompanyAndAcceptInvitation, createInitialTestUser } from "../../utils/register-user-and-return-user-info.js"; -import { setSaasEnvVariable } from "../../utils/set-saas-env-variable.js"; -import { TestUtils } from "../../utils/test.utils.js"; -import { createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions } from "../../utils/user-with-different-permissions-utils.js"; + inviteUserInCompanyAndAcceptInvitation, + createInitialTestUser, +} from '../../utils/register-user-and-return-user-info.js'; +import { setSaasEnvVariable } from '../../utils/set-saas-env-variable.js'; +import { TestUtils } from '../../utils/test.utils.js'; +import { createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions } from '../../utils/user-with-different-permissions-utils.js'; let app: INestApplication; let _testUtils: TestUtils; let currentTest: string; const mockFactory = new MockFactory(); -const newConnectionToPostgres = - mockFactory.generateConnectionToTestPostgresDBInDocker(); +const newConnectionToPostgres = mockFactory.generateConnectionToTestPostgresDBInDocker(); const updateConnection = mockFactory.generateUpdateConnectionDto(); const newGroup1 = mockFactory.generateCreateGroupDto1(); const tablePermissions = { @@ -72,7 +71,7 @@ test.after(async () => { await Cacher.clearAllCache(); await app.close(); } catch (e) { - console.error("After tests error " + e); + console.error('After tests error ' + e); } }); @@ -80,70 +79,61 @@ test.after(async () => { //****************************** CONNECTION CONTROLLER -currentTest = "GET /connections/"; +currentTest = 'GET /connections/'; -test.serial( - `${currentTest} should return connections, where second user have access`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const findAll = await request(app.getHttpServer()) - .get("/connections") - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - - t.is(findAll.status, 200); - - t.is(findAll.status, 200); - - const result = findAll.body.connections; - const nonTestConnection = result.find( - ({ connection }) => connection.id === connections.firstId, - ); - t.is(result.length, 1); - t.is(Object.hasOwn(nonTestConnection, "connection"), true); - t.is(Object.hasOwn(nonTestConnection, "accessLevel"), true); - t.is(nonTestConnection.accessLevel, AccessLevelEnum.readonly); - - t.is(Object.hasOwn(nonTestConnection.connection, "host"), true); - t.is(Object.hasOwn(result[0].connection, "host"), true); - t.is(typeof result[0].connection.port, "number"); - t.is(Object.hasOwn(result[0].connection, "port"), true); - t.is(Object.hasOwn(result[0].connection, "username"), true); - t.is(Object.hasOwn(result[0].connection, "database"), true); - t.is(Object.hasOwn(result[0].connection, "sid"), true); - t.is(Object.hasOwn(result[0].connection, "createdAt"), true); - t.is(Object.hasOwn(result[0].connection, "updatedAt"), true); - t.is(Object.hasOwn(result[0].connection, "password"), false); - t.is(Object.hasOwn(result[0].connection, "groups"), false); - t.is(Object.hasOwn(result[0].connection, "author"), false); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should return connections, where second user have access`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const findAll = await request(app.getHttpServer()) + .get('/connections') + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + + t.is(findAll.status, 200); + + t.is(findAll.status, 200); + + const result = findAll.body.connections; + const nonTestConnection = result.find(({ connection }) => connection.id === connections.firstId); + t.is(result.length, 1); + t.is(Object.hasOwn(nonTestConnection, 'connection'), true); + t.is(Object.hasOwn(nonTestConnection, 'accessLevel'), true); + t.is(nonTestConnection.accessLevel, AccessLevelEnum.readonly); + + t.is(Object.hasOwn(nonTestConnection.connection, 'host'), true); + t.is(Object.hasOwn(result[0].connection, 'host'), true); + t.is(typeof result[0].connection.port, 'number'); + t.is(Object.hasOwn(result[0].connection, 'port'), true); + t.is(Object.hasOwn(result[0].connection, 'username'), true); + t.is(Object.hasOwn(result[0].connection, 'database'), true); + t.is(Object.hasOwn(result[0].connection, 'sid'), true); + t.is(Object.hasOwn(result[0].connection, 'createdAt'), true); + t.is(Object.hasOwn(result[0].connection, 'updatedAt'), true); + t.is(Object.hasOwn(result[0].connection, 'password'), false); + t.is(Object.hasOwn(result[0].connection, 'groups'), false); + t.is(Object.hasOwn(result[0].connection, 'author'), false); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "GET /connection/one/:slug"; +currentTest = 'GET /connection/one/:slug'; test.serial(`${currentTest} should return a found connection`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -156,26 +146,26 @@ test.serial(`${currentTest} should return a found connection`, async (t) => { const searchedConnectionId = connections.firstId; const findOneResponce = await request(app.getHttpServer()) .get(`/connection/one/${searchedConnectionId}`) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); t.is(findOneResponce.status, 200); const result = findOneResponce.body.connection; t.is(result.title, newConnectionToPostgres.title); - t.is(result.type, "postgres"); + t.is(result.type, 'postgres'); t.is(result.host, newConnectionToPostgres.host); - t.is(typeof result.port, "number"); + t.is(typeof result.port, 'number'); t.is(result.port, newConnectionToPostgres.port); - t.is(result.username, "postgres"); + t.is(result.username, 'postgres'); t.is(result.database, newConnectionToPostgres.database); t.is(result.sid, null); - t.is(Object.hasOwn(result, "createdAt"), true); - t.is(Object.hasOwn(result, "updatedAt"), true); - t.is(Object.hasOwn(result, "password"), false); - t.is(Object.hasOwn(result, "groups"), false); - t.is(Object.hasOwn(result, "author"), false); + t.is(Object.hasOwn(result, 'createdAt'), true); + t.is(Object.hasOwn(result, 'updatedAt'), true); + t.is(Object.hasOwn(result, 'password'), false); + t.is(Object.hasOwn(result, 'groups'), false); + t.is(Object.hasOwn(result, 'author'), false); } catch (e) { console.error(e); throw e; @@ -187,9 +177,7 @@ test.serial( async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -203,14 +191,14 @@ test.serial( const findOneResponce = await request(app.getHttpServer()) .get(`/connection/one/${searchedConnectionId}`) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); // todo add checking connection object properties t.is(findOneResponce.status, 200); const findOneRO = JSON.parse(findOneResponce.text); - t.is(Object.hasOwn(findOneRO, "host"), false); + t.is(Object.hasOwn(findOneRO, 'host'), false); } catch (e) { console.error(e); throw e; @@ -218,52 +206,42 @@ test.serial( }, ); -currentTest = "PUT /connection"; +currentTest = 'PUT /connection'; -test.serial( - `${currentTest} should throw exception you do not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw exception you do not have permission`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const updateConnectionResponse = await request(app.getHttpServer()) - .put(`/connection/${connections.firstId}`) - .send(updateConnection) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const updateConnectionResponse = await request(app.getHttpServer()) + .put(`/connection/${connections.firstId}`) + .send(updateConnection) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(updateConnectionResponse.status, 403); - t.is( - JSON.parse(updateConnectionResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(updateConnectionResponse.status, 403); + t.is(JSON.parse(updateConnectionResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should return throw an exception, when you try update a connection without permissions in it`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -275,15 +253,12 @@ test.serial( const updateConnectionResponse = await request(app.getHttpServer()) .put(`/connection/${connections.secondId}`) .send(updateConnection) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(updateConnectionResponse.status, 403); - t.is( - JSON.parse(updateConnectionResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + t.is(JSON.parse(updateConnectionResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -291,57 +266,50 @@ test.serial( }, ); -currentTest = "DELETE /connection/:slug"; - -test.serial( - `${currentTest} should throw an exception do not have permissions`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +currentTest = 'DELETE /connection/:slug'; - const response = await request(app.getHttpServer()) - .put(`/connection/delete/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(response.status, 403); - t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); +test.serial(`${currentTest} should throw an exception do not have permissions`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - //deleted connection found in database - const findOneResponce = await request(app.getHttpServer()) - .get(`/connection/one/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const response = await request(app.getHttpServer()) + .put(`/connection/delete/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(response.status, 403); + t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); + + //deleted connection found in database + const findOneResponce = await request(app.getHttpServer()) + .get(`/connection/one/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(findOneResponce.status, 200); - t.is(JSON.parse(findOneResponce.text).connection.id, connections.firstId); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(findOneResponce.status, 200); + t.is(JSON.parse(findOneResponce.text).connection.id, connections.firstId); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception, when you try to delete connection without permission`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -353,18 +321,18 @@ test.serial( const response = await request(app.getHttpServer()) .put(`/connection/delete/${connections.secondId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 403); t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); //connection wasn't deleted const findOneResponce = await request(app.getHttpServer()) .get(`/connection/one/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(findOneResponce.status, 200); } catch (e) { @@ -374,52 +342,42 @@ test.serial( }, ); -currentTest = "POST /connection/group/:slug"; +currentTest = 'POST /connection/group/:slug'; -test.serial( - `${currentTest} should throw an exception don not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw an exception don not have permission`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 403); - t.is( - JSON.parse(createGroupResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(createGroupResponse.status, 403); + t.is(JSON.parse(createGroupResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception when you try add group in connection without permission in it`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -430,16 +388,13 @@ test.serial( } = testData; const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.secondId}`) - .set("Cookie", simpleUserToken) + .set('Cookie', simpleUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createGroupResponse.status, 403); - t.is( - JSON.parse(createGroupResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + t.is(JSON.parse(createGroupResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -447,69 +402,62 @@ test.serial( }, ); -currentTest = "PUT /connection/group/:slug"; +currentTest = 'PUT /connection/group/:slug'; -test.serial( - `${currentTest} should return connection without deleted group result`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should return connection without deleted group result`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connections.firstId}`) - .set("Cookie", adminUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connections.firstId}`) + .set('Cookie', adminUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - // create group in connection - let result = createGroupResponse.body; - t.is(createGroupResponse.status, 201); + // create group in connection + let result = createGroupResponse.body; + t.is(createGroupResponse.status, 201); - t.is(Object.hasOwn(result, "id"), true); - t.is(result.title, newGroup1.title); + t.is(Object.hasOwn(result, 'id'), true); + t.is(result.title, newGroup1.title); - const createGroupRO = JSON.parse(createGroupResponse.text); + const createGroupRO = JSON.parse(createGroupResponse.text); - const response = await request(app.getHttpServer()) - .put(`/connection/group/delete/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .send({ groupId: createGroupRO.id }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const response = await request(app.getHttpServer()) + .put(`/connection/group/delete/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .send({ groupId: createGroupRO.id }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - //after deleting group - result = response.body; + //after deleting group + result = response.body; - t.is(response.status, 403); - t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(response.status, 403); + t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception, when you try delete group in connection without permissions`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -520,27 +468,27 @@ test.serial( } = testData; const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.secondId}`) - .set("Cookie", adminUserToken) + .set('Cookie', adminUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); // create group in connection const result = createGroupResponse.body; t.is(createGroupResponse.status, 201); - t.is(Object.hasOwn(result, "id"), true); + t.is(Object.hasOwn(result, 'id'), true); t.is(result.title, newGroup1.title); const createGroupRO = JSON.parse(createGroupResponse.text); const response = await request(app.getHttpServer()) .put(`/connection/group/delete/${connections.secondId}`) - .set("Cookie", simpleUserToken) + .set('Cookie', simpleUserToken) .send({ groupId: createGroupRO.id }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 403); t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); @@ -551,14 +499,12 @@ test.serial( }, ); -currentTest = "GET /connection/groups/:slug"; +currentTest = 'GET /connection/groups/:slug'; test.serial(`${currentTest} should groups in connection`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -572,28 +518,28 @@ test.serial(`${currentTest} should groups in connection`, async (t) => { const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.firstId}`) - .set("Cookie", adminUserToken) + .set('Cookie', adminUserToken) .send(newRandomGroup2) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createGroupResponse.status, 201); const response = await request(app.getHttpServer()) .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 200); const result = JSON.parse(response.text); const _groupId = result[0].group.id; - t.is(Object.hasOwn(result[0].group, "title"), true); + t.is(Object.hasOwn(result[0].group, 'title'), true); t.is(result[0].accessLevel, AccessLevelEnum.readonly); const index = result.findIndex((el: any) => { - return el.group.title === "Admin"; + return el.group.title === 'Admin'; }); t.is(index >= 0, false); @@ -608,9 +554,7 @@ test.serial( async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -621,18 +565,18 @@ test.serial( } = testData; const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.secondId}`) - .set("Cookie", adminUserToken) + .set('Cookie', adminUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createGroupResponse.status, 201); const response = await request(app.getHttpServer()) .get(`/connection/groups/${connections.secondId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 200); const result = JSON.parse(response.text); @@ -644,158 +588,129 @@ test.serial( }, ); -currentTest = "GET /connection/permissions"; +currentTest = 'GET /connection/permissions'; -test.serial( - `${currentTest} should return permissions object for current group in current connection`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - const groupId = getGroupsRO[0].group.id; +test.serial(`${currentTest} should return permissions object for current group in current connection`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const groupId = getGroupsRO[0].group.id; - const response = await request(app.getHttpServer()) - .get( - `/connection/permissions?connectionId=${connections.firstId}&groupId=${groupId}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const result = JSON.parse(response.text); - t.is(response.status, 200); + const response = await request(app.getHttpServer()) + .get(`/connection/permissions?connectionId=${connections.firstId}&groupId=${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const result = JSON.parse(response.text); + t.is(response.status, 200); - t.is(Object.hasOwn(result, "connection"), true); - t.is(Object.hasOwn(result, "group"), true); - t.is(Object.hasOwn(result, "tables"), true); - t.is(typeof result.connection, "object"); - t.is(typeof result.group, "object"); - t.is(result.connection.connectionId, connections.firstId); - t.is(result.group.groupId, groupId); - t.is(result.connection.accessLevel, AccessLevelEnum.readonly); - t.is(result.group.accessLevel, AccessLevelEnum.readonly); - t.is(typeof result.tables, "object"); + t.is(Object.hasOwn(result, 'connection'), true); + t.is(Object.hasOwn(result, 'group'), true); + t.is(Object.hasOwn(result, 'tables'), true); + t.is(typeof result.connection, 'object'); + t.is(typeof result.group, 'object'); + t.is(result.connection.connectionId, connections.firstId); + t.is(result.group.groupId, groupId); + t.is(result.connection.accessLevel, AccessLevelEnum.readonly); + t.is(result.group.accessLevel, AccessLevelEnum.readonly); + t.is(typeof result.tables, 'object'); + + const { tables } = result; + const tableIndex = tables.findIndex((table: any) => table.tableName === firstTableInfo.testTableName); + t.is(tables.length > 0, true); + t.is(typeof tables[tableIndex], 'object'); + t.is(Object.hasOwn(tables[tableIndex], 'accessLevel'), true); + t.is(tables[tableIndex].accessLevel.visibility, tablePermissions.visibility); + t.is(tables[tableIndex].accessLevel.readonly, tablePermissions.readonly); + t.is(tables[tableIndex].accessLevel.add, tablePermissions.add); + t.is(tables[tableIndex].accessLevel.delete, tablePermissions.delete); + t.is(tables[tableIndex].accessLevel.edit, tablePermissions.edit); + } catch (e) { + console.error(e); + throw e; + } +}); - const { tables } = result; - const tableIndex = tables.findIndex( - (table: any) => table.tableName === firstTableInfo.testTableName, - ); - t.is(tables.length > 0, true); - t.is(typeof tables[tableIndex], "object"); - t.is(Object.hasOwn(tables[tableIndex], "accessLevel"), true); - t.is( - tables[tableIndex].accessLevel.visibility, - tablePermissions.visibility, - ); - t.is(tables[tableIndex].accessLevel.readonly, tablePermissions.readonly); - t.is(tables[tableIndex].accessLevel.add, tablePermissions.add); - t.is(tables[tableIndex].accessLevel.delete, tablePermissions.delete); - t.is(tables[tableIndex].accessLevel.edit, tablePermissions.edit); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -currentTest = "GET /connection/user/permissions"; - -test.serial( - `${currentTest} should return permissions object for current group in current connection`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +currentTest = 'GET /connection/user/permissions'; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - const groupId = getGroupsRO[0].group.id; +test.serial(`${currentTest} should return permissions object for current group in current connection`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const response = await request(app.getHttpServer()) - .get( - `/connection/user/permissions?connectionId=${connections.firstId}&groupId=${groupId}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(response.status, 200); - const result = JSON.parse(response.text); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const groupId = getGroupsRO[0].group.id; - t.is(Object.hasOwn(result, "connection"), true); - t.is(Object.hasOwn(result, "group"), true); - t.is(Object.hasOwn(result, "tables"), true); - t.is(typeof result.connection, "object"); - t.is(typeof result.group, "object"); - t.is(result.connection.connectionId, connections.firstId); - t.is(result.group.groupId, groupId); - t.is(result.connection.accessLevel, AccessLevelEnum.readonly); - t.is(result.group.accessLevel, AccessLevelEnum.readonly); - t.is(typeof result.tables, "object"); + const response = await request(app.getHttpServer()) + .get(`/connection/user/permissions?connectionId=${connections.firstId}&groupId=${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(response.status, 200); + const result = JSON.parse(response.text); - const { tables } = result; - const foundTableIndex = tables.findIndex( - (table) => table.tableName === firstTableInfo.testTableName, - ); - t.is(tables.length > 0, true); - t.is(typeof tables[foundTableIndex], "object"); - t.is(Object.hasOwn(tables[foundTableIndex], "accessLevel"), true); - t.is( - tables[foundTableIndex].accessLevel.visibility, - tablePermissions.visibility, - ); - t.is( - tables[foundTableIndex].accessLevel.readonly, - tablePermissions.readonly, - ); - t.is(tables[foundTableIndex].accessLevel.add, tablePermissions.add); - t.is(tables[foundTableIndex].accessLevel.delete, tablePermissions.delete); - t.is(tables[foundTableIndex].accessLevel.edit, tablePermissions.edit); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(Object.hasOwn(result, 'connection'), true); + t.is(Object.hasOwn(result, 'group'), true); + t.is(Object.hasOwn(result, 'tables'), true); + t.is(typeof result.connection, 'object'); + t.is(typeof result.group, 'object'); + t.is(result.connection.connectionId, connections.firstId); + t.is(result.group.groupId, groupId); + t.is(result.connection.accessLevel, AccessLevelEnum.readonly); + t.is(result.group.accessLevel, AccessLevelEnum.readonly); + t.is(typeof result.tables, 'object'); + + const { tables } = result; + const foundTableIndex = tables.findIndex((table) => table.tableName === firstTableInfo.testTableName); + t.is(tables.length > 0, true); + t.is(typeof tables[foundTableIndex], 'object'); + t.is(Object.hasOwn(tables[foundTableIndex], 'accessLevel'), true); + t.is(tables[foundTableIndex].accessLevel.visibility, tablePermissions.visibility); + t.is(tables[foundTableIndex].accessLevel.readonly, tablePermissions.readonly); + t.is(tables[foundTableIndex].accessLevel.add, tablePermissions.add); + t.is(tables[foundTableIndex].accessLevel.delete, tablePermissions.delete); + t.is(tables[foundTableIndex].accessLevel.edit, tablePermissions.edit); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should return permissions object for current group in current connection for current user`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -807,35 +722,33 @@ test.serial( const getGroupsResponse = await request(app.getHttpServer()) .get(`/connection/groups/${connections.secondId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); const groupId = getGroupsRO[0].group.id; const response = await request(app.getHttpServer()) - .get( - `/connection/user/permissions?connectionId=${connections.secondId}&groupId=${groupId}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/connection/user/permissions?connectionId=${connections.secondId}&groupId=${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 200); const result = JSON.parse(response.text); - t.is(Object.hasOwn(result, "connection"), true); - t.is(Object.hasOwn(result, "group"), true); - t.is(Object.hasOwn(result, "tables"), true); - t.is(typeof result.connection, "object"); - t.is(typeof result.group, "object"); + t.is(Object.hasOwn(result, 'connection'), true); + t.is(Object.hasOwn(result, 'group'), true); + t.is(Object.hasOwn(result, 'tables'), true); + t.is(typeof result.connection, 'object'); + t.is(typeof result.group, 'object'); t.is(result.connection.connectionId, connections.secondId); t.is(result.group.groupId, groupId); t.is(result.connection.accessLevel, AccessLevelEnum.none); t.is(result.group.accessLevel, AccessLevelEnum.none); - t.is(typeof result.tables, "object"); + t.is(typeof result.tables, 'object'); } catch (e) { console.error(e); throw e; @@ -845,49 +758,42 @@ test.serial( //****************************** GROUP CONTROLLER ******************************// -currentTest = "GET /groups/"; +currentTest = 'GET /groups/'; -test.serial( - `${currentTest} should return found groups with current user`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - users: { simpleUserToken }, - } = testData; +test.serial(`${currentTest} should return found groups with current user`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + users: { simpleUserToken }, + } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/groups/`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - const { groups, groupsCount } = getGroupsRO; - t.is(groupsCount, 1); - t.is(groups.length, 1); - t.is(Object.hasOwn(groups[0], "group"), true); - t.is(Object.hasOwn(groups[0], "accessLevel"), true); - - t.is(Object.hasOwn(groups[0].group, "title"), true); - t.is(Object.hasOwn(groups[0].group, "isMain"), true); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/groups/`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const { groups, groupsCount } = getGroupsRO; + t.is(groupsCount, 1); + t.is(groups.length, 1); + t.is(Object.hasOwn(groups[0], 'group'), true); + t.is(Object.hasOwn(groups[0], 'accessLevel'), true); + + t.is(Object.hasOwn(groups[0].group, 'title'), true); + t.is(Object.hasOwn(groups[0].group, 'isMain'), true); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "GET /group/users/:slug"; +currentTest = 'GET /group/users/:slug'; test.serial(`${currentTest} it should return users in groups`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -898,9 +804,9 @@ test.serial(`${currentTest} it should return users in groups`, async (t) => { } = testData; const getGroupsResponse = await request(app.getHttpServer()) .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); const nonAdminGroupIndex = getGroupsRO.findIndex((element) => { @@ -909,9 +815,9 @@ test.serial(`${currentTest} it should return users in groups`, async (t) => { const groupId = getGroupsRO[nonAdminGroupIndex].group.id; const response = await request(app.getHttpServer()) .get(`/group/users/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 200); const _getUsersRO = JSON.parse(response.text); t.is(getGroupsRO.length, 2); @@ -926,9 +832,7 @@ test.serial( async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -939,9 +843,9 @@ test.serial( } = testData; const getGroupsResponse = await request(app.getHttpServer()) .get(`/connection/groups/${connections.secondId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); @@ -949,9 +853,9 @@ test.serial( const response = await request(app.getHttpServer()) .get(`/group/users/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getUsersRO = JSON.parse(response.text); t.is(getUsersRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { @@ -961,421 +865,422 @@ test.serial( }, ); -currentTest = "PUT /group/user"; - -test.serial( - `${currentTest} should throw exception ${Messages.DONT_HAVE_PERMISSIONS}`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +currentTest = 'PUT /group/user'; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw exception ${Messages.DONT_HAVE_PERMISSIONS}`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const groupId = getGroupsRO[0].group.id; + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const email = faker.internet.email(); - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); - t.is(addUserInGroupResponse.status, 403); - t.is(Object.hasOwn(addUserInGroupRO, "message"), true); - t.is(addUserInGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const groupId = getGroupsRO[0].group.id; + + const email = faker.internet.email(); + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); + t.is(addUserInGroupResponse.status, 403); + t.is(Object.hasOwn(addUserInGroupRO, 'message'), true); + t.is(addUserInGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw exception, when group id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw exception, when group id not passed in request`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const _groupId = getGroupsRO[0].group.id; - const email = faker.internet.email(); - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", simpleUserToken) - .send({ email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); - t.is(addUserInGroupResponse.status, 400); - t.is(addUserInGroupRO.message, Messages.GROUP_ID_MISSING); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const _groupId = getGroupsRO[0].group.id; + const email = faker.internet.email(); + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', simpleUserToken) + .send({ email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); + t.is(addUserInGroupResponse.status, 400); + t.is(addUserInGroupRO.message, Messages.GROUP_ID_MISSING); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw exception, when group id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw exception, when group id passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); - const _getGroupsRO = JSON.parse(getGroupsResponse.text); - - const email = faker.internet.email(); - const groupId = faker.string.uuid(); - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); - t.is(addUserInGroupResponse.status, 400); - t.is(addUserInGroupRO.message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(getGroupsResponse.status, 200); + const _getGroupsRO = JSON.parse(getGroupsResponse.text); + + const email = faker.internet.email(); + const groupId = faker.string.uuid(); + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); + t.is(addUserInGroupResponse.status, 400); + t.is(addUserInGroupRO.message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "DELETE /group/:slug"; +currentTest = 'DELETE /group/:slug'; -test.serial( - `${currentTest} should throw ${Messages.DONT_HAVE_PERMISSIONS} exception`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw ${Messages.DONT_HAVE_PERMISSIONS} exception`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); - const groupId = JSON.parse(getGroupsResponse.text)[0].group.id; - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteGroupRO = JSON.parse(deleteGroupResponse.text); - t.is(deleteGroupResponse.status, 403); - t.is(deleteGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(getGroupsResponse.status, 200); + const groupId = JSON.parse(getGroupsResponse.text)[0].group.id; + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteGroupRO = JSON.parse(deleteGroupResponse.text); + t.is(deleteGroupResponse.status, 403); + t.is(deleteGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when you try delete admin group`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw an exception when you try delete admin group`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const adminGroupIndex = getGroupsRO.findIndex( - (group) => group.group.isMain, - ); + const adminGroupIndex = getGroupsRO.findIndex((group) => group.group.isMain); - const groupId = getGroupsRO[adminGroupIndex].group.id; - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteGroupRO = JSON.parse(deleteGroupResponse.text); - t.is(deleteGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const groupId = getGroupsRO[adminGroupIndex].group.id; + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteGroupRO = JSON.parse(deleteGroupResponse.text); + t.is(deleteGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when group id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw an exception when group id not passed in request`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const _groupId = getGroupsRO[0].group.id; - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(deleteGroupResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const _groupId = getGroupsRO[0].group.id; + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(deleteGroupResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when group id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw an exception when group id passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); + t.is(getGroupsResponse.status, 200); - const groupId = faker.string.uuid(); - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteGroupRO = JSON.parse(deleteGroupResponse.text); - t.is(deleteGroupRO.message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const groupId = faker.string.uuid(); + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteGroupRO = JSON.parse(deleteGroupResponse.text); + t.is(deleteGroupRO.message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "PUT /group/user/delete"; +currentTest = 'PUT /group/user/delete'; -test.serial( - `${currentTest} should throw an exception ${Messages.DONT_HAVE_PERMISSIONS}`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw an exception ${Messages.DONT_HAVE_PERMISSIONS}`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const groupId = getGroupsRO[0].group.id; + const groupId = getGroupsRO[0].group.id; - const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( - adminUserToken, - undefined, - app, - undefined, - ); + const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation(adminUserToken, undefined, app, undefined); - const email = thirdTestUser.email; - - const deleteUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user/delete") - .set("Cookie", simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(deleteUserInGroupResponse.status, 403); - const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); - t.is(deleteUserInGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const email = thirdTestUser.email; -test.serial( - `${currentTest} should throw exception, when group id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const deleteUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user/delete') + .set('Cookie', simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(deleteUserInGroupResponse.status, 403); + const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); + t.is(deleteUserInGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); +test.serial(`${currentTest} should throw exception, when group id not passed in request`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const _groupId = getGroupsRO[0].group.id; + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( - adminUserToken, - undefined, - app, - undefined, - ); + const _groupId = getGroupsRO[0].group.id; - const email = thirdTestUser.email; - - const deleteUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user/delete") - .set("Cookie", simpleUserToken) - .send({ email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(deleteUserInGroupResponse.status, 400); - const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); - t.is(deleteUserInGroupRO.message, Messages.GROUP_ID_MISSING); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation(adminUserToken, undefined, app, undefined); + + const email = thirdTestUser.email; + + const deleteUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user/delete') + .set('Cookie', simpleUserToken) + .send({ email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(deleteUserInGroupResponse.status, 400); + const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); + t.is(deleteUserInGroupRO.message, Messages.GROUP_ID_MISSING); + } catch (e) { + console.error(e); + throw e; + } +}); //****************************** PERMISSION CONTROLLER TESTS ******************************// -currentTest = "PUT permissions/:slug"; +currentTest = 'PUT permissions/:slug'; + +test.serial(`${currentTest} should throw an exception do not have permission`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connections.firstId}`) + .set('Cookie', adminUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + t.is(createGroupResponse.status, 201); + const newGroupId = createGroupRO.id; + + const permissions = { + connection: { + connectionId: connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: firstTableInfo.testTableName, + accessLevel: { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: false, + }, + }, + ], + }; + + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createOrUpdatePermissionRO = JSON.parse(createOrUpdatePermissionResponse.text); + t.is(createOrUpdatePermissionResponse.status, 403); + t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( - `${currentTest} should throw an exception do not have permission`, + `${currentTest} should throw ${Messages.DONT_HAVE_PERMISSIONS} exception object when you update permissions`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -1383,53 +1288,48 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connections.firstId}`) - .set("Cookie", adminUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - t.is(createGroupResponse.status, 201); - const newGroupId = createGroupRO.id; + + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + + const groupId = getGroupsRO[0].group.id; const permissions = { connection: { + accessLevel: AccessLevelEnum.none, connectionId: connections.firstId, - accessLevel: AccessLevelEnum.readonly, }, group: { - groupId: newGroupId, accessLevel: AccessLevelEnum.readonly, + groupId: groupId, }, tables: [ { - tableName: firstTableInfo.testTableName, accessLevel: { - visibility: true, + add: false, + delete: false, + edit: true, readonly: false, - add: true, - delete: true, - edit: false, + visibility: true, }, + tableName: firstTableInfo.testTableName, }, ], }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${groupId}?connectionId=${connections.firstId}`) .send({ permissions }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createOrUpdatePermissionRO = JSON.parse( - createOrUpdatePermissionResponse.text, - ); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createOrUpdatePermissionRO = JSON.parse(createOrUpdatePermissionResponse.text); t.is(createOrUpdatePermissionResponse.status, 403); t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { @@ -1439,227 +1339,127 @@ test.serial( }, ); -test.serial( - `${currentTest} should throw ${Messages.DONT_HAVE_PERMISSIONS} exception object when you update permissions`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - - const groupId = getGroupsRO[0].group.id; +test.serial(`${currentTest} should throw an exception, when you try change admin group`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups: { firstAdminGroupId }, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const permissions = { - connection: { - accessLevel: AccessLevelEnum.none, - connectionId: connections.firstId, - }, - group: { - accessLevel: AccessLevelEnum.readonly, - groupId: groupId, - }, - tables: [ - { - accessLevel: { - add: false, - delete: false, - edit: true, - readonly: false, - visibility: true, - }, - tableName: firstTableInfo.testTableName, + const permissions = { + connection: { + connectionId: connections.firstId, + accessLevel: AccessLevelEnum.edit, + }, + group: { + groupId: firstAdminGroupId, + accessLevel: AccessLevelEnum.none, + }, + tables: [ + { + tableName: firstTableInfo.testTableName, + accessLevel: { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: false, }, - ], - }; - - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put(`/permissions/${groupId}?connectionId=${connections.firstId}`) - .send({ permissions }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createOrUpdatePermissionRO = JSON.parse( - createOrUpdatePermissionResponse.text, - ); - t.is(createOrUpdatePermissionResponse.status, 403); - t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw an exception, when you try change admin group`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups: { firstAdminGroupId }, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const permissions = { - connection: { - connectionId: connections.firstId, - accessLevel: AccessLevelEnum.edit, - }, - group: { - groupId: firstAdminGroupId, - accessLevel: AccessLevelEnum.none, }, - tables: [ - { - tableName: firstTableInfo.testTableName, - accessLevel: { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: false, - }, - }, - ], - }; - - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put(`/permissions/${firstAdminGroupId}`) - .send({ permissions }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createOrUpdatePermissionRO = JSON.parse( - createOrUpdatePermissionResponse.text, - ); - t.is(createOrUpdatePermissionResponse.status, 403); - t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + ], + }; + + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${firstAdminGroupId}`) + .send({ permissions }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createOrUpdatePermissionRO = JSON.parse(createOrUpdatePermissionResponse.text); + t.is(createOrUpdatePermissionResponse.status, 403); + t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); //****************************** TABLE CONTROLLER TESTS ******************************// -currentTest = "GET /connection/tables/:slug"; +currentTest = 'GET /connection/tables/:slug'; -test.serial( - `${currentTest} should return all tables in connection`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesInConnection = await request(app.getHttpServer()) - .get(`/connection/tables/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesInConnection.status, 200); - const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); - t.is(getTablesInConnectionRO.length > 0, true); - const tableIndex = getTablesInConnectionRO.findIndex( - (table: any) => table.table === testData.firstTableInfo.testTableName, - ); - t.is( - getTablesInConnectionRO[tableIndex].table, - testData.firstTableInfo.testTableName, - ); - t.is(typeof getTablesInConnectionRO[tableIndex].permissions, "object"); - const { - visibility, - readonly, - add, - delete: del, - edit, - } = getTablesInConnectionRO[0].permissions; - t.is(visibility, tablePermissions.visibility); - t.is(readonly, tablePermissions.readonly); - t.is(del, tablePermissions.delete); - t.is(edit, tablePermissions.edit); - t.is(add, tablePermissions.add); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should return all tables in connection`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesInConnection = await request(app.getHttpServer()) + .get(`/connection/tables/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesInConnection.status, 200); + const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); + t.is(getTablesInConnectionRO.length > 0, true); + const tableIndex = getTablesInConnectionRO.findIndex( + (table: any) => table.table === testData.firstTableInfo.testTableName, + ); + t.is(getTablesInConnectionRO[tableIndex].table, testData.firstTableInfo.testTableName); + t.is(typeof getTablesInConnectionRO[tableIndex].permissions, 'object'); + const { visibility, readonly, add, delete: del, edit } = getTablesInConnectionRO[0].permissions; + t.is(visibility, tablePermissions.visibility); + t.is(readonly, tablePermissions.readonly); + t.is(del, tablePermissions.delete); + t.is(edit, tablePermissions.edit); + t.is(add, tablePermissions.add); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception, when connection id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesInConnection = await request(app.getHttpServer()) - .get(`/connection/tables/`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesInConnection.status, 404); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception, when connection id not passed in request`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesInConnection = await request(app.getHttpServer()) + .get(`/connection/tables/`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesInConnection.status, 404); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception, when connection id passed in request is incorrect`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -1671,9 +1471,9 @@ test.serial( const fakeConnectionId = faker.string.uuid(); const getTablesInConnection = await request(app.getHttpServer()) .get(`/connection/tables/${fakeConnectionId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getTablesInConnection.status, 400); const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); t.is(getTablesInConnectionRO.message, Messages.CONNECTION_NOT_FOUND); @@ -1684,14 +1484,12 @@ test.serial( }, ); -currentTest = "GET /table/rows/:slug"; +currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return found rows from table`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -1701,26 +1499,17 @@ test.serial(`${currentTest} should return found rows from table`, async (t) => { users: { adminUserToken, simpleUserToken }, } = testData; const getTableRows = await request(app.getHttpServer()) - .get( - `/table/rows/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/table/rows/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getTableRows.status, 200); const getTableRowsRO = JSON.parse(getTableRows.text); - const { - rows, - primaryColumns, - pagination, - sortable_by, - structure, - foreignKeys, - } = getTableRowsRO; + const { rows, primaryColumns, pagination, sortable_by, structure, foreignKeys } = getTableRowsRO; t.is(rows.length, Constants.DEFAULT_PAGINATION.perPage); t.is(primaryColumns.length, 1); - t.is(primaryColumns[0].column_name, "id"); - t.is(primaryColumns[0].data_type, "integer"); + t.is(primaryColumns[0].column_name, 'id'); + t.is(primaryColumns[0].data_type, 'integer'); t.is(sortable_by.length, 0); t.is(structure.length, 5); t.is(foreignKeys.length, 0); @@ -1730,109 +1519,10 @@ test.serial(`${currentTest} should return found rows from table`, async (t) => { } }); -test.serial( - `${currentTest} should throw an exception when connection id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesRows = await request(app.getHttpServer()) - .get(`/table/rows/?tableName=${firstTableInfo.testTableName}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesRows.status, 404); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrec`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeId = faker.string.uuid(); - const getTableRows = await request(app.getHttpServer()) - .get( - `/table/rows/${fakeId}?tableName=${testData.firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTableRows.status, 403); - const getTablesInConnectionRO = JSON.parse(getTableRows.text); - t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTablesRows = await request(app.getHttpServer()) - .get(`/table/rows/${connections.firstId}?tableName=${fakeTableName}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesRows.status, 403); - const getTablesInConnectionRO = JSON.parse(getTablesRows.text); - t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -currentTest = "GET /table/structure/:slug"; - -test.serial(`${currentTest} should return table structure`, async (t) => { +test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -1841,175 +1531,221 @@ test.serial(`${currentTest} should return table structure`, async (t) => { secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const getTablesStructure = await request(app.getHttpServer()) - .get( - `/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - const getTableStructureRO = JSON.parse(getTablesStructure.text); - - t.is(getTablesStructure.status, 200); - const { - structure, - primaryColumns, - foreignKeys, - readonly_fields, - table_widgets, - } = getTableStructureRO; - t.is(structure.length, 5); - t.is(primaryColumns.length, 1); - t.is(primaryColumns[0].column_name, "id"); - t.is(primaryColumns[0].data_type, "integer"); - t.is(readonly_fields.length, 0); - t.is(table_widgets.length, 0); - t.is(foreignKeys.length, 0); + const getTablesRows = await request(app.getHttpServer()) + .get(`/table/rows/?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesRows.status, 404); } catch (e) { console.error(e); throw e; } }); -test.serial( - `${currentTest} should throw an exception when connection id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrec`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeId = faker.string.uuid(); + const getTableRows = await request(app.getHttpServer()) + .get(`/table/rows/${fakeId}?tableName=${testData.firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRows.status, 403); + const getTablesInConnectionRO = JSON.parse(getTableRows.text); + t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); - const getTablesStructure = await request(app.getHttpServer()) - .get(`/table/structure/?tableName=${firstTableInfo.testTableName}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 404); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTablesRows = await request(app.getHttpServer()) + .get(`/table/rows/${connections.firstId}?tableName=${fakeTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesRows.status, 403); + const getTablesInConnectionRO = JSON.parse(getTablesRows.text); + t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +currentTest = 'GET /table/structure/:slug'; - const fakeConnectionId = faker.string.uuid(); - const getTablesStructure = await request(app.getHttpServer()) - .get( - `/table/structure/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 403); - const getTablesStructureRO = JSON.parse(getTablesStructure.text); - t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should return table structure`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); -test.serial( - `${currentTest} should throw an exception when table name not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesStructure = await request(app.getHttpServer()) - .get(`/table/structure/${connections.firstId}?tableName=`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 400); - const getTablesStructureRO = JSON.parse(getTablesStructure.text); - t.is(getTablesStructureRO.message, Messages.TABLE_NAME_MISSING); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const getTableStructureRO = JSON.parse(getTablesStructure.text); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTablesStructure = await request(app.getHttpServer()) - .get( - `/table/structure/${connections.firstId}?tableName=${fakeTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 403); - const getTablesStructureRO = JSON.parse(getTablesStructure.text); - t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(getTablesStructure.status, 200); + const { structure, primaryColumns, foreignKeys, readonly_fields, table_widgets } = getTableStructureRO; + t.is(structure.length, 5); + t.is(primaryColumns.length, 1); + t.is(primaryColumns[0].column_name, 'id'); + t.is(primaryColumns[0].data_type, 'integer'); + t.is(readonly_fields.length, 0); + t.is(table_widgets.length, 0); + t.is(foreignKeys.length, 0); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "POST /table/row/:slug"; +test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 404); + } catch (e) { + console.error(e); + throw e; + } +}); + +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const fakeConnectionId = faker.string.uuid(); + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 403); + const getTablesStructureRO = JSON.parse(getTablesStructure.text); + t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); + +test.serial(`${currentTest} should throw an exception when table name not passed in request`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${connections.firstId}?tableName=`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 400); + const getTablesStructureRO = JSON.parse(getTablesStructure.text); + t.is(getTablesStructureRO.message, Messages.TABLE_NAME_MISSING); + } catch (e) { + console.error(e); + throw e; + } +}); + +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${connections.firstId}?tableName=${fakeTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 403); + const getTablesStructureRO = JSON.parse(getTablesStructure.text); + t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); + +currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should return added row`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -2025,132 +1761,113 @@ test.serial(`${currentTest} should return added row`, async (t) => { const created_at = new Date(); const updated_at = new Date(); const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) + .post(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) .send({ [firstTableInfo.testTableColumnName]: randomName, [firstTableInfo.testTableSecondColumnName]: randomEmail, created_at: created_at, updated_at: updated_at, }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const addRowInTableRO = JSON.parse(addRowInTable.text); t.is(addRowInTable.status, 201); - t.is(Object.hasOwn(addRowInTableRO.row, "id"), true); + t.is(Object.hasOwn(addRowInTableRO.row, 'id'), true); t.is(addRowInTableRO.row[firstTableInfo.testTableColumnName], randomName); - t.is( - addRowInTableRO.row[firstTableInfo.testTableSecondColumnName], - randomEmail, - ); - t.is(Object.hasOwn(addRowInTableRO.row, "created_at"), true); - t.is(Object.hasOwn(addRowInTableRO.row, "updated_at"), true); - t.is(Object.hasOwn(addRowInTableRO, "structure"), true); - t.is(Object.hasOwn(addRowInTableRO, "foreignKeys"), true); - t.is(Object.hasOwn(addRowInTableRO, "primaryColumns"), true); - t.is(Object.hasOwn(addRowInTableRO, "readonly_fields"), true); + t.is(addRowInTableRO.row[firstTableInfo.testTableSecondColumnName], randomEmail); + t.is(Object.hasOwn(addRowInTableRO.row, 'created_at'), true); + t.is(Object.hasOwn(addRowInTableRO.row, 'updated_at'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); } catch (e) { console.error(e); throw e; } }); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const fakeConnectionId = faker.string.uuid(); - const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`, - ) - .send({ - [firstTableInfo.testTableColumnName]: randomName, - [firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeConnectionId = faker.string.uuid(); + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`) + .send({ + [firstTableInfo.testTableColumnName]: randomName, + [firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTable = await request(app.getHttpServer()) - .post(`/table/row/${connections.firstId}?tableName=${fakeTableName}`) - .send({ - [firstTableInfo.testTableColumnName]: randomName, - [firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${connections.firstId}?tableName=${fakeTableName}`) + .send({ + [firstTableInfo.testTableColumnName]: randomName, + [firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "PUT /table/row/:slug"; +currentTest = 'PUT /table/row/:slug'; test.serial( `${currentTest} should throw an exception do not have permission, when you do not have edit permission`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -2165,18 +1882,16 @@ test.serial( const created_at = new Date(); const updated_at = new Date(); const updateRowInTable = await request(app.getHttpServer()) - .put( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=2`, - ) + .put(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=2`) .send({ name: randomName, email: randomEmail, created_at: created_at, updated_at: updated_at, }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const addRowInTableRO = JSON.parse(updateRowInTable.text); t.is(updateRowInTable.status, 403); t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); @@ -2187,100 +1902,222 @@ test.serial( }, ); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const fakeConnectionId = faker.string.uuid(); - const addRowInTable = await request(app.getHttpServer()) - .put( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`, - ) - .send({ - name: randomName, - email: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeConnectionId = faker.string.uuid(); + const addRowInTable = await request(app.getHttpServer()) + .put(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`) + .send({ + name: randomName, + email: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTable = await request(app.getHttpServer()) - .put( - `/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`, - ) - .send({ - name: randomName, - email: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTable = await request(app.getHttpServer()) + .put(`/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`) + .send({ + name: randomName, + email: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); + +currentTest = 'DELETE /table/row/:slug'; + +test.serial(`${currentTest} should return delete result`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const deleteRowInTable = await request(app.getHttpServer()) + .delete(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=19`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTable.status, 200); + } catch (e) { + console.error(e); + throw e; + } +}); + +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeConnectionId = faker.string.uuid(); + const deleteRowInTable = await request(app.getHttpServer()) + .delete(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteRowInTableRO = JSON.parse(deleteRowInTable.text); + t.is(deleteRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + t.is(deleteRowInTable.status, 403); + } catch (e) { + console.error(e); + throw e; + } +}); + +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTable = await request(app.getHttpServer()) + .delete(`/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteRowInTabbleRO = JSON.parse(deleteRowInTable.text); + t.is(deleteRowInTabbleRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "DELETE /table/row/:slug"; +currentTest = 'GET /table/row/:slug'; + +test.serial(`${currentTest} should return row`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getRowInTable = await request(app.getHttpServer()) + .get(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=7`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getRowInTableRO = JSON.parse(getRowInTable.text); + t.is(getRowInTable.status, 200); + t.is(getRowInTableRO.row.id, 7); + t.is(Object.hasOwn(getRowInTableRO.row, 'created_at'), true); + t.is(Object.hasOwn(getRowInTableRO.row, 'updated_at'), true); + t.is(Object.hasOwn(getRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(getRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(getRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getRowInTableRO, 'readonly_fields'), true); + } catch (e) { + console.error(e); + throw e; + } +}); + +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeConnectionId = faker.string.uuid(); + const addRowInTable = await request(app.getHttpServer()) + .get(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=5`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial(`${currentTest} should return delete result`, async (t) => { +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -2289,96 +2126,28 @@ test.serial(`${currentTest} should return delete result`, async (t) => { secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const deleteRowInTable = await request(app.getHttpServer()) - .delete( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=19`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(deleteRowInTable.status, 200); + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTable = await request(app.getHttpServer()) + .get(`/table/row/${connections.firstId}?tableName=${fakeTableName}&id=5`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; } }); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeConnectionId = faker.string.uuid(); - const deleteRowInTable = await request(app.getHttpServer()) - .delete( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteRowInTableRO = JSON.parse(deleteRowInTable.text); - t.is(deleteRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - t.is(deleteRowInTable.status, 403); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTable = await request(app.getHttpServer()) - .delete( - `/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteRowInTabbleRO = JSON.parse(deleteRowInTable.text); - t.is(deleteRowInTabbleRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +//****************************** TABLE LOGS CONTROLLER TESTS ******************************// -currentTest = "GET /table/row/:slug"; +currentTest = 'GET /logs/:slug'; -test.serial(`${currentTest} should return row`, async (t) => { +test.serial(`${currentTest} should return all found logs in connection'`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -2387,168 +2156,52 @@ test.serial(`${currentTest} should return row`, async (t) => { secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const getRowInTable = await request(app.getHttpServer()) - .get( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=7`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getRowInTableRO = JSON.parse(getRowInTable.text); - t.is(getRowInTable.status, 200); - t.is(getRowInTableRO.row.id, 7); - t.is(Object.hasOwn(getRowInTableRO.row, "created_at"), true); - t.is(Object.hasOwn(getRowInTableRO.row, "updated_at"), true); - t.is(Object.hasOwn(getRowInTableRO, "structure"), true); - t.is(Object.hasOwn(getRowInTableRO, "foreignKeys"), true); - t.is(Object.hasOwn(getRowInTableRO, "primaryColumns"), true); - t.is(Object.hasOwn(getRowInTableRO, "readonly_fields"), true); + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .send({ + [firstTableInfo.testTableColumnName]: randomName, + [firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTable.status, 201); + + const getTableLogs = await request(app.getHttpServer()) + .get(`/logs/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getRowInTableRO = JSON.parse(getTableLogs.text); + + t.is(getRowInTableRO.logs.length, 1); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'table_name'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'received_data'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'old_data'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'cognitoUserName'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'email'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'operationType'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'operationStatusResult'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'createdAt'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'connection_id'), true); } catch (e) { console.error(e); throw e; } }); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeConnectionId = faker.string.uuid(); - const addRowInTable = await request(app.getHttpServer()) - .get( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=5`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTable = await request(app.getHttpServer()) - .get( - `/table/row/${connections.firstId}?tableName=${fakeTableName}&id=5`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -//****************************** TABLE LOGS CONTROLLER TESTS ******************************// - -currentTest = "GET /logs/:slug"; - -test.serial( - `${currentTest} should return all found logs in connection'`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .send({ - [firstTableInfo.testTableColumnName]: randomName, - [firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(addRowInTable.status, 201); - - const getTableLogs = await request(app.getHttpServer()) - .get(`/logs/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getRowInTableRO = JSON.parse(getTableLogs.text); - - t.is(getRowInTableRO.logs.length, 1); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "table_name"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "received_data"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "old_data"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "cognitoUserName"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "email"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "operationType"), true); - t.is( - Object.hasOwn(getRowInTableRO.logs[0], "operationStatusResult"), - true, - ); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "createdAt"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "connection_id"), true); - } catch (e) { - console.error(e); - throw e; - } - }, -); - test.serial( `${currentTest} should not return all found logs in connection, when table audit is disabled in connection'`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -2562,62 +2215,51 @@ test.serial( const created_at = new Date(); const updated_at = new Date(); - const updateConnection = - mockFactory.generateConnectionToTestPostgresDBInDocker(); + const updateConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); const updateConnectionResponse = await request(app.getHttpServer()) .put(`/connection/${connections.firstId}`) .send(updateConnection) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(updateConnectionResponse.status, 200); - const newConnectionProperties = - mockFactory.generateConnectionPropertiesUserExcluded( - firstTableInfo.testTableName, - false, - ); + const newConnectionProperties = mockFactory.generateConnectionPropertiesUserExcluded( + firstTableInfo.testTableName, + false, + ); - const createConnectionPropertiesResponse = await request( - app.getHttpServer(), - ) + const createConnectionPropertiesResponse = await request(app.getHttpServer()) .post(`/connection/properties/${connections.firstId}`) .send(newConnectionProperties) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const createConnectionPropertiesResponseRO = JSON.parse( - createConnectionPropertiesResponse.text, - ); - console.log( - "🚀 ~ test ~ createConnectionPropertiesResponseRO:", - createConnectionPropertiesResponseRO, - ); + const createConnectionPropertiesResponseRO = JSON.parse(createConnectionPropertiesResponse.text); + console.log('🚀 ~ test ~ createConnectionPropertiesResponseRO:', createConnectionPropertiesResponseRO); t.is(createConnectionPropertiesResponse.status, 201); const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) + .post(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) .send({ [firstTableInfo.testTableColumnName]: randomName, [firstTableInfo.testTableSecondColumnName]: randomEmail, created_at: created_at, updated_at: updated_at, }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(addRowInTable.status, 201); const getTableLogs = await request(app.getHttpServer()) .get(`/logs/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getRowInTableRO = JSON.parse(getTableLogs.text); t.is(getRowInTableRO.logs.length, 0); @@ -2630,14 +2272,12 @@ test.serial( //****************************** TABLE SETTINGS CONTROLLER TESTS ******************************// -currentTest = "GET /settings/"; +currentTest = 'GET /settings/'; test.skip(`${currentTest} should return empty object when table settings was not created`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -2647,12 +2287,10 @@ test.skip(`${currentTest} should return empty object when table settings was not users: { adminUserToken, simpleUserToken }, } = testData; const getTableSettings = await request(app.getHttpServer()) - .get( - `/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getTableSettingsRO = JSON.parse(getTableSettings.text); t.is(getTableSettings.status, 200); t.deepEqual(getTableSettingsRO, {}); @@ -2662,177 +2300,58 @@ test.skip(`${currentTest} should return empty object when table settings was not } }); -test.serial( - `${currentTest} 'should should return created table settings`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - ['id'], - [firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); - - const getTableSettings = await request(app.getHttpServer()) - .get( - `/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const _getTableSettingsRO = JSON.parse(getTableSettings.text); - t.is(getTableSettings.status, 200); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw an exception when you try get settings in connection where you do not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(createTableSettingsResponse.status, 201); - - const getTableSettings = await request(app.getHttpServer()) - .get( - `/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getTableSettingsRO = JSON.parse(getTableSettings.text); - t.is(getTableSettings.status, 403); - t.is(getTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -currentTest = "POST /settings/"; +test.serial(`${currentTest} 'should should return created table settings`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; -test.serial( - `${currentTest} should throw an exception do not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + ['id'], + [firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - 'users', - ['id'], - ['email'], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 403); - t.is( - JSON.parse(createTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const getTableSettings = await request(app.getHttpServer()) + .get(`/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const _getTableSettingsRO = JSON.parse(getTableSettings.text); + t.is(getTableSettings.status, 200); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( - `${currentTest} should throw an exception when you try create settings in connection where you do not have permission`, + `${currentTest} should throw an exception when you try get settings in connection where you do not have permission`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -2842,32 +2361,35 @@ test.serial( users: { adminUserToken, simpleUserToken }, } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}`, - ) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) .send(createTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 403); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const createTableSettingsRO = JSON.parse( - createTableSettingsResponse.text, - ); - t.is(createTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); + t.is(createTableSettingsResponse.status, 201); + + const getTableSettings = await request(app.getHttpServer()) + .get(`/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getTableSettingsRO = JSON.parse(getTableSettings.text); + t.is(getTableSettings.status, 403); + t.is(getTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -2875,191 +2397,84 @@ test.serial( }, ); -currentTest = "PUT /settings/"; +currentTest = 'POST /settings/'; test.serial(`${currentTest} should throw an exception do not have permission`, async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - ['id'], - [firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const updateTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - [firstTableInfo.testTableSecondColumnName], - ['id'], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + 'users', + ['id'], + ['email'], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); - const updateTableSettingsResponse = await request(app.getHttpServer()) - .put( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`, - ) - .send(updateTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(updateTableSettingsResponse.status, 403); - t.is( - JSON.parse(updateTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`) + .send(createTableSettingsDTO) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 403); + t.is(JSON.parse(createTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( - `${currentTest} should throw an exception when you try update settings in connection where you do not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); - - const updateTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - [firstTableInfo.testTableSecondColumnName], - ['id'], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + `${currentTest} should throw an exception when you try create settings in connection where you do not have permission`, + async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const updateTableSettingsResponse = await request(app.getHttpServer()) - .put( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}}`, - ) - .send(updateTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(updateTableSettingsResponse.status, 403); - t.is( - JSON.parse(updateTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, ); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -currentTest = "DELETE /settings/"; - -test.serial(`${currentTest} should return array without deleted table settings`, async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - ['id'], - [firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}`) .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); - - const deleteTableSettingsResponse = await request(app.getHttpServer()) - .delete( - `/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 403); - t.is(deleteTableSettingsResponse.status, 403); - t.is( - JSON.parse(deleteTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); + t.is(createTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -3067,73 +2482,72 @@ test.serial(`${currentTest} should return array without deleted table settings`, }, ); -test.serial( - `${currentTest} should throw an exception when you try delete settings in connection where you do not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); +currentTest = 'PUT /settings/'; - const deleteTableSettingsResponse = await request(app.getHttpServer()) - .delete( - `/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteTableSettingsRO = JSON.parse( - deleteTableSettingsResponse.text, - ); - t.is(deleteTableSettingsResponse.status, 403); - t.is(deleteTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception do not have permission`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + ['id'], + [firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); -//****************************** TABLE WIDGETS CONTROLLER TESTS ******************************// + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const updateTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + [firstTableInfo.testTableSecondColumnName], + ['id'], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); -currentTest = "GET /widgets/:slug"; + const updateTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`) + .send(updateTableSettingsDTO) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(updateTableSettingsResponse.status, 403); + t.is(JSON.parse(updateTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( - `${currentTest} should return empty widgets array when widgets not created`, + `${currentTest} should throw an exception when you try update settings in connection where you do not have permission`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -3142,16 +2556,46 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const getTableWidgets = await request(app.getHttpServer()) - .get( - `/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(getTableWidgets.status, 200); - t.is(getTableWidgetsRO.length, 0); + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const updateTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + [firstTableInfo.testTableSecondColumnName], + ['id'], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); + + const updateTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}}`) + .send(updateTableSettingsDTO) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(updateTableSettingsResponse.status, 403); + t.is(JSON.parse(updateTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -3159,14 +2603,60 @@ test.serial( }, ); +currentTest = 'DELETE /settings/'; + +test.serial(`${currentTest} should return array without deleted table settings`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + ['id'], + [firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const deleteTableSettingsResponse = await request(app.getHttpServer()) + .delete(`/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteTableSettingsResponse.status, 403); + t.is(JSON.parse(deleteTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); + test.serial( - `${currentTest} should return array of table widgets for table`, + `${currentTest} should throw an exception when you try delete settings in connection where you do not have permission`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -3175,67 +2665,34 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); - const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", adminUserToken) - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 201); - t.is(typeof createTableWidgetRO, "object"); - t.is(createTableWidgetRO.length, 2); - t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); - t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); - t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); - const getTableWidgets = await request(app.getHttpServer()) - .get( - `/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - t.is(getTableWidgets.status, 200); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(getTableWidgetsRO.length, 2); - - const getTableStructureResponse = await request(app.getHttpServer()) - .get( - `/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - t.is(getTableStructureResponse.status, 200); - const getTableStructureRO = JSON.parse(getTableStructureResponse.text); - t.is(Object.hasOwn(getTableStructureRO, "table_widgets"), true); - t.is(getTableStructureRO.table_widgets.length, 2); - t.truthy( - getTableStructureRO.table_widgets.some( - (w) => w.field_name === newTableWidgets[0].field_name, - ), - ); - t.truthy( - getTableStructureRO.table_widgets.some( - (w) => w.widget_type === newTableWidgets[1].widget_type, - ), - ); - t.is( - compareTableWidgetsArrays( - getTableStructureRO.table_widgets, - newTableWidgets, - ), - true, - ); + const deleteTableSettingsResponse = await request(app.getHttpServer()) + .delete(`/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteTableSettingsRO = JSON.parse(deleteTableSettingsResponse.text); + t.is(deleteTableSettingsResponse.status, 403); + t.is(deleteTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -3243,14 +2700,100 @@ test.serial( }, ); +//****************************** TABLE WIDGETS CONTROLLER TESTS ******************************// + +currentTest = 'GET /widgets/:slug'; + +test.serial(`${currentTest} should return empty widgets array when widgets not created`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(getTableWidgets.status, 200); + t.is(getTableWidgetsRO.length, 0); + } catch (e) { + console.error(e); + throw e; + } +}); + +test.serial(`${currentTest} should return array of table widgets for table`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', adminUserToken) + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 201); + t.is(typeof createTableWidgetRO, 'object'); + t.is(createTableWidgetRO.length, 2); + t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); + t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); + t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); + + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + t.is(getTableWidgets.status, 200); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(getTableWidgetsRO.length, 2); + + const getTableStructureResponse = await request(app.getHttpServer()) + .get(`/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + t.is(getTableStructureResponse.status, 200); + const getTableStructureRO = JSON.parse(getTableStructureResponse.text); + t.is(Object.hasOwn(getTableStructureRO, 'table_widgets'), true); + t.is(getTableStructureRO.table_widgets.length, 2); + t.truthy(getTableStructureRO.table_widgets.some((w) => w.field_name === newTableWidgets[0].field_name)); + t.truthy(getTableStructureRO.table_widgets.some((w) => w.widget_type === newTableWidgets[1].widget_type)); + t.is(compareTableWidgetsArrays(getTableStructureRO.table_widgets, newTableWidgets), true); + } catch (e) { + console.error(e); + throw e; + } +}); + test.serial( `${currentTest} should throw an exception, when you try to get widgets from connection, when you do not have permissions`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -3259,31 +2802,26 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) + .post(`/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", adminUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', adminUserToken) + .set('Accept', 'application/json'); const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 201); - t.is(typeof createTableWidgetRO, "object"); + t.is(typeof createTableWidgetRO, 'object'); t.is(createTableWidgetRO.length, 2); const getTableWidgets = await request(app.getHttpServer()) - .get( - `/widgets/${connections.secondId}?tableName=${secondTableInfo.testTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .get(`/widgets/${connections.secondId}?tableName=${secondTableInfo.testTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); const getTableWidgetsRO = JSON.parse(getTableWidgets.text); t.is(getTableWidgets.status, 403); t.is(getTableWidgetsRO.message, Messages.DONT_HAVE_PERMISSIONS); @@ -3294,57 +2832,47 @@ test.serial( }, ); -currentTest = "POST /widget/:slug"; +currentTest = 'POST /widget/:slug'; -test.serial( - `${currentTest} should throw an exception do not have permissions`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw an exception do not have permissions`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); - const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}}`, - ) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 403); - t.is(createTableWidgetRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 403); + t.is(createTableWidgetRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception, when you try add widget in connection, when you do not have permissions`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -3353,20 +2881,17 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.secondId}?tableName=${secondTableInfo.testTableName}`, - ) + .post(`/widget/${connections.secondId}?tableName=${secondTableInfo.testTableName}`) .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 403); t.is(createTableWidgetRO.message, Messages.DONT_HAVE_PERMISSIONS); diff --git a/backend/test/ava-tests/non-saas-tests/non-saas-user-with-table-only-permissions-e2e.test.ts b/backend/test/ava-tests/non-saas-tests/non-saas-user-with-table-only-permissions-e2e.test.ts index cba39d145..acab0363e 100644 --- a/backend/test/ava-tests/non-saas-tests/non-saas-user-with-table-only-permissions-e2e.test.ts +++ b/backend/test/ava-tests/non-saas-tests/non-saas-user-with-table-only-permissions-e2e.test.ts @@ -1,39 +1,38 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable security/detect-object-injection */ -import { faker } from "@faker-js/faker"; -import { INestApplication, ValidationPipe } from "@nestjs/common"; -import { Test } from "@nestjs/testing"; -import test from "ava"; -import { ValidationError } from "class-validator"; -import cookieParser from "cookie-parser"; -import request from "supertest"; -import { ApplicationModule } from "../../../src/app.module.js"; -import { WinstonLogger } from "../../../src/entities/logging/winston-logger.js"; +import { faker } from '@faker-js/faker'; +import { INestApplication, ValidationPipe } from '@nestjs/common'; +import { Test } from '@nestjs/testing'; +import test from 'ava'; +import { ValidationError } from 'class-validator'; +import cookieParser from 'cookie-parser'; +import request from 'supertest'; +import { ApplicationModule } from '../../../src/app.module.js'; +import { WinstonLogger } from '../../../src/entities/logging/winston-logger.js'; +import { AccessLevelEnum, QueryOrderingEnum } from '../../../src/enums/index.js'; +import { AllExceptionsFilter } from '../../../src/exceptions/all-exceptions.filter.js'; +import { ValidationException } from '../../../src/exceptions/custom-exceptions/validation-exception.js'; +import { Messages } from '../../../src/exceptions/text/messages.js'; +import { Cacher } from '../../../src/helpers/cache/cacher.js'; +import { Constants } from '../../../src/helpers/constants/constants.js'; +import { DatabaseModule } from '../../../src/shared/database/database.module.js'; +import { DatabaseService } from '../../../src/shared/database/database.service.js'; +import { MockFactory } from '../../mock.factory.js'; +import { compareTableWidgetsArrays } from '../../utils/compare-table-widgets-arrays.js'; import { - AccessLevelEnum, - QueryOrderingEnum, -} from "../../../src/enums/index.js"; -import { AllExceptionsFilter } from "../../../src/exceptions/all-exceptions.filter.js"; -import { ValidationException } from "../../../src/exceptions/custom-exceptions/validation-exception.js"; -import { Messages } from "../../../src/exceptions/text/messages.js"; -import { Cacher } from "../../../src/helpers/cache/cacher.js"; -import { Constants } from "../../../src/helpers/constants/constants.js"; -import { DatabaseModule } from "../../../src/shared/database/database.module.js"; -import { DatabaseService } from "../../../src/shared/database/database.service.js"; -import { MockFactory } from "../../mock.factory.js"; -import { compareTableWidgetsArrays } from "../../utils/compare-table-widgets-arrays.js"; -import { inviteUserInCompanyAndAcceptInvitation, createInitialTestUser } from "../../utils/register-user-and-return-user-info.js"; -import { setSaasEnvVariable } from "../../utils/set-saas-env-variable.js"; -import { TestUtils } from "../../utils/test.utils.js"; -import { createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions } from "../../utils/user-with-different-permissions-utils.js"; + inviteUserInCompanyAndAcceptInvitation, + createInitialTestUser, +} from '../../utils/register-user-and-return-user-info.js'; +import { setSaasEnvVariable } from '../../utils/set-saas-env-variable.js'; +import { TestUtils } from '../../utils/test.utils.js'; +import { createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions } from '../../utils/user-with-different-permissions-utils.js'; let app: INestApplication; let _testUtils: TestUtils; let currentTest: string; const mockFactory = new MockFactory(); -const _newConnectionToPostgres = - mockFactory.generateConnectionToTestPostgresDBInDocker(); +const _newConnectionToPostgres = mockFactory.generateConnectionToTestPostgresDBInDocker(); const updateConnection = mockFactory.generateUpdateConnectionDto(); const newGroup1 = mockFactory.generateCreateGroupDto1(); const tablePermissions = { @@ -72,7 +71,7 @@ test.after(async () => { await Cacher.clearAllCache(); await app.close(); } catch (e) { - console.error("After tests error " + e); + console.error('After tests error ' + e); } }); @@ -80,55 +79,44 @@ test.after(async () => { //****************************** CONNECTION CONTROLLER -currentTest = "GET /connections/"; +currentTest = 'GET /connections/'; -test.serial( - `${currentTest} should return connections, where second user have access`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const findAll = await request(app.getHttpServer()) - .get("/connections") - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - - t.is(findAll.status, 200); - const _resultRO = JSON.parse(findAll.text); - const result = findAll.body.connections; - t.is(result.length, 1); - const nonTestConnection = result.find( - ({ connection }) => connection.id === connections.firstId, - ); - for (const key in nonTestConnection.connection) { - t.is(Constants.CONNECTION_KEYS_NONE_PERMISSION.includes(key), true); - } - } catch (e) { - console.error(e); - throw e; +test.serial(`${currentTest} should return connections, where second user have access`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const findAll = await request(app.getHttpServer()) + .get('/connections') + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + + t.is(findAll.status, 200); + const _resultRO = JSON.parse(findAll.text); + const result = findAll.body.connections; + t.is(result.length, 1); + const nonTestConnection = result.find(({ connection }) => connection.id === connections.firstId); + for (const key in nonTestConnection.connection) { + t.is(Constants.CONNECTION_KEYS_NONE_PERMISSION.includes(key), true); } - }, -); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "GET /connection/one/:slug"; +currentTest = 'GET /connection/one/:slug'; test.serial(`${currentTest} should return a found connection`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -141,9 +129,9 @@ test.serial(`${currentTest} should return a found connection`, async (t) => { const searchedConnectionId = connections.firstId; const findOneResponce = await request(app.getHttpServer()) .get(`/connection/one/${searchedConnectionId}`) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); t.is(findOneResponce.status, 200); const result = findOneResponce.body.connection; @@ -160,10 +148,7 @@ test.serial( `${currentTest} should throw an exception, when you do not have permission in this connection`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -177,14 +162,14 @@ test.serial( const findOneResponce = await request(app.getHttpServer()) .get(`/connection/one/${searchedConnectionId}`) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); // todo add checking connection object properties t.is(findOneResponce.status, 200); const findOneRO = JSON.parse(findOneResponce.text); - t.is(Object.hasOwn(findOneRO, "host"), false); + t.is(Object.hasOwn(findOneRO, 'host'), false); } catch (e) { console.error(e); throw e; @@ -192,52 +177,40 @@ test.serial( }, ); -currentTest = "PUT /connection"; +currentTest = 'PUT /connection'; -test.serial( - `${currentTest} should throw exception you do not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw exception you do not have permission`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const updateConnectionResponse = await request(app.getHttpServer()) - .put(`/connection/${connections.firstId}`) - .send(updateConnection) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const updateConnectionResponse = await request(app.getHttpServer()) + .put(`/connection/${connections.firstId}`) + .send(updateConnection) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(updateConnectionResponse.status, 403); - t.is( - JSON.parse(updateConnectionResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(updateConnectionResponse.status, 403); + t.is(JSON.parse(updateConnectionResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should return throw an exception, when you try update a connection without permissions in it`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -249,15 +222,12 @@ test.serial( const updateConnectionResponse = await request(app.getHttpServer()) .put(`/connection/${connections.secondId}`) .send(updateConnection) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(updateConnectionResponse.status, 403); - t.is( - JSON.parse(updateConnectionResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + t.is(JSON.parse(updateConnectionResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -265,57 +235,48 @@ test.serial( }, ); -currentTest = "DELETE /connection/:slug"; - -test.serial( - `${currentTest} should throw an exception do not have permissions`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +currentTest = 'DELETE /connection/:slug'; - const response = await request(app.getHttpServer()) - .put(`/connection/delete/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(response.status, 403); - t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); +test.serial(`${currentTest} should throw an exception do not have permissions`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - //deleted connection found in database - const findOneResponce = await request(app.getHttpServer()) - .get(`/connection/one/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const response = await request(app.getHttpServer()) + .put(`/connection/delete/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(response.status, 403); + t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); + + //deleted connection found in database + const findOneResponce = await request(app.getHttpServer()) + .get(`/connection/one/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(findOneResponce.status, 200); - t.is(JSON.parse(findOneResponce.text).connection.id, connections.firstId); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(findOneResponce.status, 200); + t.is(JSON.parse(findOneResponce.text).connection.id, connections.firstId); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception, when you try to delete connection without permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -327,18 +288,18 @@ test.serial( const response = await request(app.getHttpServer()) .put(`/connection/delete/${connections.secondId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 403); t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); //connection wasn't deleted const findOneResponce = await request(app.getHttpServer()) .get(`/connection/one/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(findOneResponce.status, 200); } catch (e) { @@ -348,52 +309,40 @@ test.serial( }, ); -currentTest = "POST /connection/group/:slug"; +currentTest = 'POST /connection/group/:slug'; -test.serial( - `${currentTest} should throw an exception don not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw an exception don not have permission`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 403); - t.is( - JSON.parse(createGroupResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(createGroupResponse.status, 403); + t.is(JSON.parse(createGroupResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception when you try add group in connection without permission in it`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -404,16 +353,13 @@ test.serial( } = testData; const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.secondId}`) - .set("Cookie", simpleUserToken) + .set('Cookie', simpleUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createGroupResponse.status, 403); - t.is( - JSON.parse(createGroupResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + t.is(JSON.parse(createGroupResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -421,69 +367,60 @@ test.serial( }, ); -currentTest = "PUT /connection/group/:slug"; +currentTest = 'PUT /connection/group/:slug'; -test.serial( - `${currentTest} should return connection without deleted group result`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should return connection without deleted group result`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connections.firstId}`) - .set("Cookie", adminUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connections.firstId}`) + .set('Cookie', adminUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - // create group in connection - let result = createGroupResponse.body; - t.is(createGroupResponse.status, 201); + // create group in connection + let result = createGroupResponse.body; + t.is(createGroupResponse.status, 201); - t.is(Object.hasOwn(result, "id"), true); - t.is(result.title, newGroup1.title); + t.is(Object.hasOwn(result, 'id'), true); + t.is(result.title, newGroup1.title); - const createGroupRO = JSON.parse(createGroupResponse.text); + const createGroupRO = JSON.parse(createGroupResponse.text); - const response = await request(app.getHttpServer()) - .put(`/connection/group/delete/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .send({ groupId: createGroupRO.id }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const response = await request(app.getHttpServer()) + .put(`/connection/group/delete/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .send({ groupId: createGroupRO.id }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - //after deleting group - result = response.body; + //after deleting group + result = response.body; - t.is(response.status, 403); - t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(response.status, 403); + t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception, when you try delete group in connection without permissions`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -494,27 +431,27 @@ test.serial( } = testData; const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.secondId}`) - .set("Cookie", adminUserToken) + .set('Cookie', adminUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); // create group in connection const result = createGroupResponse.body; t.is(createGroupResponse.status, 201); - t.is(Object.hasOwn(result, "id"), true); + t.is(Object.hasOwn(result, 'id'), true); t.is(result.title, newGroup1.title); const createGroupRO = JSON.parse(createGroupResponse.text); const response = await request(app.getHttpServer()) .put(`/connection/group/delete/${connections.secondId}`) - .set("Cookie", simpleUserToken) + .set('Cookie', simpleUserToken) .send({ groupId: createGroupRO.id }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 403); t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); @@ -525,14 +462,11 @@ test.serial( }, ); -currentTest = "GET /connection/groups/:slug"; +currentTest = 'GET /connection/groups/:slug'; test.serial(`${currentTest} should groups in connection`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -546,28 +480,28 @@ test.serial(`${currentTest} should groups in connection`, async (t) => { const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.firstId}`) - .set("Cookie", adminUserToken) + .set('Cookie', adminUserToken) .send(newRandomGroup2) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createGroupResponse.status, 201); const response = await request(app.getHttpServer()) .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 200); const result = JSON.parse(response.text); const _groupId = result[0].group.id; - t.is(Object.hasOwn(result[0].group, "title"), true); + t.is(Object.hasOwn(result[0].group, 'title'), true); t.is(result[0].accessLevel, AccessLevelEnum.none); const index = result.findIndex((el: any) => { - return el.group.title === "Admin"; + return el.group.title === 'Admin'; }); t.is(index >= 0, false); @@ -581,10 +515,7 @@ test.serial( `${currentTest} it should throw an exception, when you try get groups in connection, where you do not have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -595,18 +526,18 @@ test.serial( } = testData; const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.secondId}`) - .set("Cookie", adminUserToken) + .set('Cookie', adminUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createGroupResponse.status, 201); const response = await request(app.getHttpServer()) .get(`/connection/groups/${connections.secondId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 200); const result = JSON.parse(response.text); @@ -618,16 +549,126 @@ test.serial( }, ); -currentTest = "GET /connection/permissions"; +currentTest = 'GET /connection/permissions'; + +test.serial(`${currentTest} should return permissions object for current group in current connection`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const groupId = getGroupsRO[0].group.id; + + const response = await request(app.getHttpServer()) + .get(`/connection/permissions?connectionId=${connections.firstId}&groupId=${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const result = JSON.parse(response.text); + t.is(response.status, 200); + + t.is(Object.hasOwn(result, 'connection'), true); + t.is(Object.hasOwn(result, 'group'), true); + t.is(Object.hasOwn(result, 'tables'), true); + t.is(typeof result.connection, 'object'); + t.is(typeof result.group, 'object'); + t.is(result.connection.connectionId, connections.firstId); + t.is(result.group.groupId, groupId); + t.is(result.connection.accessLevel, AccessLevelEnum.none); + t.is(result.group.accessLevel, AccessLevelEnum.none); + t.is(typeof result.tables, 'object'); + + const { tables } = result; + const tableIndex = tables.findIndex((table: any) => table.tableName === firstTableInfo.testTableName); + t.is(tables.length > 0, true); + t.is(typeof tables[tableIndex], 'object'); + t.is(Object.hasOwn(tables[tableIndex], 'accessLevel'), true); + t.is(tables[tableIndex].accessLevel.visibility, tablePermissions.visibility); + t.is(tables[tableIndex].accessLevel.readonly, tablePermissions.readonly); + t.is(tables[tableIndex].accessLevel.add, tablePermissions.add); + t.is(tables[tableIndex].accessLevel.delete, tablePermissions.delete); + t.is(tables[tableIndex].accessLevel.edit, tablePermissions.edit); + } catch (e) { + console.error(e); + throw e; + } +}); + +currentTest = 'GET /connection/user/permissions'; + +test.serial(`${currentTest} should return permissions object for current group in current connection`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const groupId = getGroupsRO[0].group.id; + + const response = await request(app.getHttpServer()) + .get(`/connection/user/permissions?connectionId=${connections.firstId}&groupId=${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(response.status, 200); + const result = JSON.parse(response.text); + + t.is(Object.hasOwn(result, 'connection'), true); + t.is(Object.hasOwn(result, 'group'), true); + t.is(Object.hasOwn(result, 'tables'), true); + t.is(typeof result.connection, 'object'); + t.is(typeof result.group, 'object'); + t.is(result.connection.connectionId, connections.firstId); + t.is(result.group.groupId, groupId); + t.is(result.connection.accessLevel, AccessLevelEnum.none); + t.is(result.group.accessLevel, AccessLevelEnum.none); + t.is(typeof result.tables, 'object'); + + const { tables } = result; + const foundTableIndex = tables.findIndex((table) => table.tableName === firstTableInfo.testTableName); + t.is(tables.length > 0, true); + t.is(typeof tables[foundTableIndex], 'object'); + t.is(Object.hasOwn(tables[foundTableIndex], 'accessLevel'), true); + t.is(tables[foundTableIndex].accessLevel.visibility, tablePermissions.visibility); + t.is(tables[foundTableIndex].accessLevel.readonly, tablePermissions.readonly); + t.is(tables[foundTableIndex].accessLevel.add, tablePermissions.add); + t.is(tables[foundTableIndex].accessLevel.delete, tablePermissions.delete); + t.is(tables[foundTableIndex].accessLevel.edit, tablePermissions.edit); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( - `${currentTest} should return permissions object for current group in current connection`, + `${currentTest} should return permissions object for current group in current connection for current user`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -636,51 +677,36 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; + const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/connection/groups/${connections.secondId}`) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); + const groupId = getGroupsRO[0].group.id; const response = await request(app.getHttpServer()) - .get( - `/connection/permissions?connectionId=${connections.firstId}&groupId=${groupId}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const result = JSON.parse(response.text); + .get(`/connection/user/permissions?connectionId=${connections.secondId}&groupId=${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(response.status, 200); + const result = JSON.parse(response.text); - t.is(Object.hasOwn(result, "connection"), true); - t.is(Object.hasOwn(result, "group"), true); - t.is(Object.hasOwn(result, "tables"), true); - t.is(typeof result.connection, "object"); - t.is(typeof result.group, "object"); - t.is(result.connection.connectionId, connections.firstId); + t.is(Object.hasOwn(result, 'connection'), true); + t.is(Object.hasOwn(result, 'group'), true); + t.is(Object.hasOwn(result, 'tables'), true); + t.is(typeof result.connection, 'object'); + t.is(typeof result.group, 'object'); + t.is(result.connection.connectionId, connections.secondId); t.is(result.group.groupId, groupId); t.is(result.connection.accessLevel, AccessLevelEnum.none); t.is(result.group.accessLevel, AccessLevelEnum.none); - t.is(typeof result.tables, "object"); - - const { tables } = result; - const tableIndex = tables.findIndex( - (table: any) => table.tableName === firstTableInfo.testTableName, - ); - t.is(tables.length > 0, true); - t.is(typeof tables[tableIndex], "object"); - t.is(Object.hasOwn(tables[tableIndex], "accessLevel"), true); - t.is( - tables[tableIndex].accessLevel.visibility, - tablePermissions.visibility, - ); - t.is(tables[tableIndex].accessLevel.readonly, tablePermissions.readonly); - t.is(tables[tableIndex].accessLevel.add, tablePermissions.add); - t.is(tables[tableIndex].accessLevel.delete, tablePermissions.delete); - t.is(tables[tableIndex].accessLevel.edit, tablePermissions.edit); + t.is(typeof result.tables, 'object'); } catch (e) { console.error(e); throw e; @@ -688,225 +714,81 @@ test.serial( }, ); -currentTest = "GET /connection/user/permissions"; +//****************************** GROUP CONTROLLER ******************************// -test.serial( - `${currentTest} should return permissions object for current group in current connection`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - const groupId = getGroupsRO[0].group.id; - - const response = await request(app.getHttpServer()) - .get( - `/connection/user/permissions?connectionId=${connections.firstId}&groupId=${groupId}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(response.status, 200); - const result = JSON.parse(response.text); - - t.is(Object.hasOwn(result, "connection"), true); - t.is(Object.hasOwn(result, "group"), true); - t.is(Object.hasOwn(result, "tables"), true); - t.is(typeof result.connection, "object"); - t.is(typeof result.group, "object"); - t.is(result.connection.connectionId, connections.firstId); - t.is(result.group.groupId, groupId); - t.is(result.connection.accessLevel, AccessLevelEnum.none); - t.is(result.group.accessLevel, AccessLevelEnum.none); - t.is(typeof result.tables, "object"); - - const { tables } = result; - const foundTableIndex = tables.findIndex( - (table) => table.tableName === firstTableInfo.testTableName, - ); - t.is(tables.length > 0, true); - t.is(typeof tables[foundTableIndex], "object"); - t.is(Object.hasOwn(tables[foundTableIndex], "accessLevel"), true); - t.is( - tables[foundTableIndex].accessLevel.visibility, - tablePermissions.visibility, - ); - t.is( - tables[foundTableIndex].accessLevel.readonly, - tablePermissions.readonly, - ); - t.is(tables[foundTableIndex].accessLevel.add, tablePermissions.add); - t.is(tables[foundTableIndex].accessLevel.delete, tablePermissions.delete); - t.is(tables[foundTableIndex].accessLevel.edit, tablePermissions.edit); - } catch (e) { - console.error(e); - throw e; - } - }, -); +currentTest = 'GET /groups/'; -test.serial( - `${currentTest} should return permissions object for current group in current connection for current user`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.secondId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - - const groupId = getGroupsRO[0].group.id; - - const response = await request(app.getHttpServer()) - .get( - `/connection/user/permissions?connectionId=${connections.secondId}&groupId=${groupId}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(response.status, 200); - const result = JSON.parse(response.text); - - t.is(Object.hasOwn(result, "connection"), true); - t.is(Object.hasOwn(result, "group"), true); - t.is(Object.hasOwn(result, "tables"), true); - t.is(typeof result.connection, "object"); - t.is(typeof result.group, "object"); - t.is(result.connection.connectionId, connections.secondId); - t.is(result.group.groupId, groupId); - t.is(result.connection.accessLevel, AccessLevelEnum.none); - t.is(result.group.accessLevel, AccessLevelEnum.none); - t.is(typeof result.tables, "object"); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -//****************************** GROUP CONTROLLER ******************************// - -currentTest = "GET /groups/"; - -test.serial( - `${currentTest} should return found groups with current user`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - users: { simpleUserToken }, - } = testData; +test.serial(`${currentTest} should return found groups with current user`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + users: { simpleUserToken }, + } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/groups/`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - const { groups, groupsCount } = getGroupsRO; - t.is(groupsCount, 1); - t.is(groups.length, 1); - t.is(Object.hasOwn(groups[0], "group"), true); - t.is(Object.hasOwn(groups[0], "accessLevel"), true); - - t.is(Object.hasOwn(groups[0].group, "title"), true); - t.is(Object.hasOwn(groups[0].group, "isMain"), true); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/groups/`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const { groups, groupsCount } = getGroupsRO; + t.is(groupsCount, 1); + t.is(groups.length, 1); + t.is(Object.hasOwn(groups[0], 'group'), true); + t.is(Object.hasOwn(groups[0], 'accessLevel'), true); + + t.is(Object.hasOwn(groups[0].group, 'title'), true); + t.is(Object.hasOwn(groups[0].group, 'isMain'), true); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "GET /group/users/:slug"; -test.serial( - `${currentTest} it should throw exception ${Messages.DONT_HAVE_PERMISSIONS}`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - const nonAdminGroupIndex = getGroupsRO.findIndex((element) => { - return !element.group.isMain; - }); - const groupId = getGroupsRO[nonAdminGroupIndex].group.id; - const response = await request(app.getHttpServer()) - .get(`/group/users/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(response.status, 403); - const getUsersRO = JSON.parse(response.text); - t.is(Object.hasOwn(getUsersRO, "message"), true); - t.is(getUsersRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +currentTest = 'GET /group/users/:slug'; +test.serial(`${currentTest} it should throw exception ${Messages.DONT_HAVE_PERMISSIONS}`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const nonAdminGroupIndex = getGroupsRO.findIndex((element) => { + return !element.group.isMain; + }); + const groupId = getGroupsRO[nonAdminGroupIndex].group.id; + const response = await request(app.getHttpServer()) + .get(`/group/users/${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(response.status, 403); + const getUsersRO = JSON.parse(response.text); + t.is(Object.hasOwn(getUsersRO, 'message'), true); + t.is(getUsersRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} it should throw an exception when you try to receive user in group where you dont have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -917,9 +799,9 @@ test.serial( } = testData; const getGroupsResponse = await request(app.getHttpServer()) .get(`/connection/groups/${connections.secondId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); @@ -927,9 +809,9 @@ test.serial( const response = await request(app.getHttpServer()) .get(`/group/users/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getUsersRO = JSON.parse(response.text); t.is(getUsersRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { @@ -939,490 +821,409 @@ test.serial( }, ); -currentTest = "PUT /group/user"; - -test.serial( - `${currentTest} should throw exception ${Messages.DONT_HAVE_PERMISSIONS}`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - - const groupId = getGroupsRO[0].group.id; - - const email = faker.internet.email(); - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); - t.is(addUserInGroupResponse.status, 403); - t.is(Object.hasOwn(addUserInGroupRO, "message"), true); - t.is(addUserInGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw exception, when group id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - - const _groupId = getGroupsRO[0].group.id; - const email = faker.internet.email(); - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", simpleUserToken) - .send({ email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); - t.is(addUserInGroupResponse.status, 400); - t.is(addUserInGroupRO.message, Messages.GROUP_ID_MISSING); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw exception, when group id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(getGroupsResponse.status, 200); - const _getGroupsRO = JSON.parse(getGroupsResponse.text); - - const email = faker.internet.email(); - const groupId = faker.string.uuid(); - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); - t.is(addUserInGroupResponse.status, 400); - t.is(addUserInGroupRO.message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -currentTest = "DELETE /group/:slug"; +currentTest = 'PUT /group/user'; -test.serial( - `${currentTest} should throw ${Messages.DONT_HAVE_PERMISSIONS} exception`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(getGroupsResponse.status, 200); - const groupId = JSON.parse(getGroupsResponse.text)[0].group.id; - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteGroupRO = JSON.parse(deleteGroupResponse.text); - t.is(deleteGroupResponse.status, 403); - t.is(deleteGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw an exception when you try delete admin group`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - - const adminGroupIndex = getGroupsRO.findIndex( - (group) => group.group.isMain, - ); - - const groupId = getGroupsRO[adminGroupIndex].group.id; - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteGroupRO = JSON.parse(deleteGroupResponse.text); - t.is(deleteGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw exception ${Messages.DONT_HAVE_PERMISSIONS}`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; -test.serial( - `${currentTest} should throw an exception when group id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + + const groupId = getGroupsRO[0].group.id; + + const email = faker.internet.email(); + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); + t.is(addUserInGroupResponse.status, 403); + t.is(Object.hasOwn(addUserInGroupRO, 'message'), true); + t.is(addUserInGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); +test.serial(`${currentTest} should throw exception, when group id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + + const _groupId = getGroupsRO[0].group.id; + const email = faker.internet.email(); + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', simpleUserToken) + .send({ email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); + t.is(addUserInGroupResponse.status, 400); + t.is(addUserInGroupRO.message, Messages.GROUP_ID_MISSING); + } catch (e) { + console.error(e); + throw e; + } +}); - const _groupId = getGroupsRO[0].group.id; - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(deleteGroupResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw exception, when group id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getGroupsResponse.status, 200); + const _getGroupsRO = JSON.parse(getGroupsResponse.text); + + const email = faker.internet.email(); + const groupId = faker.string.uuid(); + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); + t.is(addUserInGroupResponse.status, 400); + t.is(addUserInGroupRO.message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when group id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +currentTest = 'DELETE /group/:slug'; - t.is(getGroupsResponse.status, 200); +test.serial(`${currentTest} should throw ${Messages.DONT_HAVE_PERMISSIONS} exception`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getGroupsResponse.status, 200); + const groupId = JSON.parse(getGroupsResponse.text)[0].group.id; + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteGroupRO = JSON.parse(deleteGroupResponse.text); + t.is(deleteGroupResponse.status, 403); + t.is(deleteGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); - const groupId = faker.string.uuid(); - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteGroupRO = JSON.parse(deleteGroupResponse.text); - t.is(deleteGroupRO.message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when you try delete admin group`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + + const adminGroupIndex = getGroupsRO.findIndex((group) => group.group.isMain); + + const groupId = getGroupsRO[adminGroupIndex].group.id; + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteGroupRO = JSON.parse(deleteGroupResponse.text); + t.is(deleteGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "PUT /group/user/delete"; +test.serial(`${currentTest} should throw an exception when group id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + + const _groupId = getGroupsRO[0].group.id; + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(deleteGroupResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception ${Messages.DONT_HAVE_PERMISSIONS}`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw an exception when group id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getGroupsResponse.status, 200); + + const groupId = faker.string.uuid(); + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteGroupRO = JSON.parse(deleteGroupResponse.text); + t.is(deleteGroupRO.message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } +}); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); +currentTest = 'PUT /group/user/delete'; - const groupId = getGroupsRO[0].group.id; +test.serial(`${currentTest} should throw an exception ${Messages.DONT_HAVE_PERMISSIONS}`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( - adminUserToken, - undefined, - app, - undefined, - ); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const email = thirdTestUser.email; - - const deleteUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user/delete") - .set("Cookie", simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(deleteUserInGroupResponse.status, 403); - const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); - t.is(deleteUserInGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const groupId = getGroupsRO[0].group.id; -test.serial( - `${currentTest} should throw exception, when group id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation(adminUserToken, undefined, app, undefined); - t.is(getGroupsResponse.status, 200); - const _getGroupsRO = JSON.parse(getGroupsResponse.text); + const email = thirdTestUser.email; - const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( - adminUserToken, - undefined, - app, - undefined, - ); + const deleteUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user/delete') + .set('Cookie', simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(deleteUserInGroupResponse.status, 403); + const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); + t.is(deleteUserInGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); - const email = thirdTestUser.email; - - const deleteUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user/delete") - .set("Cookie", simpleUserToken) - .send({ email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(deleteUserInGroupResponse.status, 400); - const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); - t.is(deleteUserInGroupRO.message, Messages.GROUP_ID_MISSING); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw exception, when group id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getGroupsResponse.status, 200); + const _getGroupsRO = JSON.parse(getGroupsResponse.text); + + const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation(adminUserToken, undefined, app, undefined); + + const email = thirdTestUser.email; + + const deleteUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user/delete') + .set('Cookie', simpleUserToken) + .send({ email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(deleteUserInGroupResponse.status, 400); + const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); + t.is(deleteUserInGroupRO.message, Messages.GROUP_ID_MISSING); + } catch (e) { + console.error(e); + throw e; + } +}); //****************************** PERMISSION CONTROLLER TESTS ******************************// -currentTest = "PUT permissions/:slug"; +currentTest = 'PUT permissions/:slug'; -test.serial( - `${currentTest} should throw an exception do not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connections.firstId}`) - .set("Cookie", adminUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - t.is(createGroupResponse.status, 201); - const newGroupId = createGroupRO.id; +test.serial(`${currentTest} should throw an exception do not have permission`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connections.firstId}`) + .set('Cookie', adminUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + t.is(createGroupResponse.status, 201); + const newGroupId = createGroupRO.id; - const permissions = { - connection: { - connectionId: connections.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, - }, - tables: [ - { - tableName: firstTableInfo.testTableName, - accessLevel: { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: false, - }, + const permissions = { + connection: { + connectionId: connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: firstTableInfo.testTableName, + accessLevel: { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: false, }, - ], - }; - - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createOrUpdatePermissionRO = JSON.parse( - createOrUpdatePermissionResponse.text, - ); - t.is(createOrUpdatePermissionResponse.status, 403); - t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + }, + ], + }; + + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createOrUpdatePermissionRO = JSON.parse(createOrUpdatePermissionResponse.text); + t.is(createOrUpdatePermissionResponse.status, 403); + t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw ${Messages.DONT_HAVE_PERMISSIONS} exception object when you update permissions`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -1433,9 +1234,9 @@ test.serial( const getGroupsResponse = await request(app.getHttpServer()) .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); @@ -1465,17 +1266,13 @@ test.serial( ], }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) .put(`/permissions/${groupId}?connectionId=${connections.firstId}`) .send({ permissions }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createOrUpdatePermissionRO = JSON.parse( - createOrUpdatePermissionResponse.text, - ); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createOrUpdatePermissionRO = JSON.parse(createOrUpdatePermissionResponse.text); t.is(createOrUpdatePermissionResponse.status, 403); t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { @@ -1485,157 +1282,123 @@ test.serial( }, ); -test.serial( - `${currentTest} should throw an exception, when you try change admin group`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups: { firstAdminGroupId }, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw an exception, when you try change admin group`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups: { firstAdminGroupId }, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const permissions = { - connection: { - connectionId: connections.firstId, - accessLevel: AccessLevelEnum.edit, - }, - group: { - groupId: firstAdminGroupId, - accessLevel: AccessLevelEnum.none, - }, - tables: [ - { - tableName: firstTableInfo.testTableName, - accessLevel: { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: false, - }, + const permissions = { + connection: { + connectionId: connections.firstId, + accessLevel: AccessLevelEnum.edit, + }, + group: { + groupId: firstAdminGroupId, + accessLevel: AccessLevelEnum.none, + }, + tables: [ + { + tableName: firstTableInfo.testTableName, + accessLevel: { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: false, }, - ], - }; - - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put(`/permissions/${firstAdminGroupId}`) - .send({ permissions }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createOrUpdatePermissionRO = JSON.parse( - createOrUpdatePermissionResponse.text, - ); - t.is(createOrUpdatePermissionResponse.status, 403); - t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + }, + ], + }; + + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${firstAdminGroupId}`) + .send({ permissions }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createOrUpdatePermissionRO = JSON.parse(createOrUpdatePermissionResponse.text); + t.is(createOrUpdatePermissionResponse.status, 403); + t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); //****************************** TABLE CONTROLLER TESTS ******************************// -currentTest = "GET /connection/tables/:slug"; +currentTest = 'GET /connection/tables/:slug'; -test.serial( - `${currentTest} should return all tables in connection`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesInConnection = await request(app.getHttpServer()) - .get(`/connection/tables/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesInConnection.status, 200); - const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); - t.is(getTablesInConnectionRO.length > 0, true); - const tableIndex = getTablesInConnectionRO.findIndex( - (table: any) => table.table === testData.firstTableInfo.testTableName, - ); - t.is( - getTablesInConnectionRO[tableIndex].table, - testData.firstTableInfo.testTableName, - ); - t.is(typeof getTablesInConnectionRO[tableIndex].permissions, "object"); - const { - visibility, - readonly, - add, - delete: del, - edit, - } = getTablesInConnectionRO[0].permissions; - t.is(visibility, tablePermissions.visibility); - t.is(readonly, tablePermissions.readonly); - t.is(del, tablePermissions.delete); - t.is(edit, tablePermissions.edit); - t.is(add, tablePermissions.add); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should return all tables in connection`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesInConnection = await request(app.getHttpServer()) + .get(`/connection/tables/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesInConnection.status, 200); + const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); + t.is(getTablesInConnectionRO.length > 0, true); + const tableIndex = getTablesInConnectionRO.findIndex( + (table: any) => table.table === testData.firstTableInfo.testTableName, + ); + t.is(getTablesInConnectionRO[tableIndex].table, testData.firstTableInfo.testTableName); + t.is(typeof getTablesInConnectionRO[tableIndex].permissions, 'object'); + const { visibility, readonly, add, delete: del, edit } = getTablesInConnectionRO[0].permissions; + t.is(visibility, tablePermissions.visibility); + t.is(readonly, tablePermissions.readonly); + t.is(del, tablePermissions.delete); + t.is(edit, tablePermissions.edit); + t.is(add, tablePermissions.add); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception, when connection id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesInConnection = await request(app.getHttpServer()) - .get(`/connection/tables/`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesInConnection.status, 404); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception, when connection id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesInConnection = await request(app.getHttpServer()) + .get(`/connection/tables/`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesInConnection.status, 404); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception, when connection id passed in request is incorrect`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -1647,9 +1410,9 @@ test.serial( const fakeConnectionId = faker.string.uuid(); const getTablesInConnection = await request(app.getHttpServer()) .get(`/connection/tables/${fakeConnectionId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getTablesInConnection.status, 400); const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); t.is(getTablesInConnectionRO.message, Messages.CONNECTION_NOT_FOUND); @@ -1660,14 +1423,11 @@ test.serial( }, ); -currentTest = "GET /table/rows/:slug"; +currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return found rows from table`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -1677,26 +1437,17 @@ test.serial(`${currentTest} should return found rows from table`, async (t) => { users: { adminUserToken, simpleUserToken }, } = testData; const getTableRows = await request(app.getHttpServer()) - .get( - `/table/rows/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/table/rows/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getTableRows.status, 200); const getTableRowsRO = JSON.parse(getTableRows.text); - const { - rows, - primaryColumns, - pagination, - sortable_by, - structure, - foreignKeys, - } = getTableRowsRO; + const { rows, primaryColumns, pagination, sortable_by, structure, foreignKeys } = getTableRowsRO; t.is(rows.length, Constants.DEFAULT_PAGINATION.perPage); t.is(primaryColumns.length, 1); - t.is(primaryColumns[0].column_name, "id"); - t.is(primaryColumns[0].data_type, "integer"); + t.is(primaryColumns[0].column_name, 'id'); + t.is(primaryColumns[0].data_type, 'integer'); t.is(sortable_by.length, 0); t.is(structure.length, 5); t.is(foreignKeys.length, 0); @@ -1706,109 +1457,86 @@ test.serial(`${currentTest} should return found rows from table`, async (t) => { } }); -test.serial( - `${currentTest} should throw an exception when connection id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesRows = await request(app.getHttpServer()) - .get(`/table/rows/?tableName=${firstTableInfo.testTableName}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesRows.status, 404); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesRows = await request(app.getHttpServer()) + .get(`/table/rows/?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesRows.status, 404); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrec`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeId = faker.string.uuid(); - const getTableRows = await request(app.getHttpServer()) - .get( - `/table/rows/${fakeId}?tableName=${testData.firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTableRows.status, 403); - const getTablesInConnectionRO = JSON.parse(getTableRows.text); - t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrec`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeId = faker.string.uuid(); + const getTableRows = await request(app.getHttpServer()) + .get(`/table/rows/${fakeId}?tableName=${testData.firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRows.status, 403); + const getTablesInConnectionRO = JSON.parse(getTableRows.text); + t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTablesRows = await request(app.getHttpServer()) - .get(`/table/rows/${connections.firstId}?tableName=${fakeTableName}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesRows.status, 403); - const getTablesInConnectionRO = JSON.parse(getTablesRows.text); - t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTablesRows = await request(app.getHttpServer()) + .get(`/table/rows/${connections.firstId}?tableName=${fakeTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesRows.status, 403); + const getTablesInConnectionRO = JSON.parse(getTablesRows.text); + t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "GET /table/structure/:slug"; +currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -1818,27 +1546,19 @@ test.serial(`${currentTest} should return table structure`, async (t) => { users: { adminUserToken, simpleUserToken }, } = testData; const getTablesStructure = await request(app.getHttpServer()) - .get( - `/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getTableStructureRO = JSON.parse(getTablesStructure.text); t.is(getTablesStructure.status, 200); - const { - structure, - primaryColumns, - foreignKeys, - readonly_fields, - table_widgets, - } = getTableStructureRO; + const { structure, primaryColumns, foreignKeys, readonly_fields, table_widgets } = getTableStructureRO; t.is(structure.length, 5); t.is(primaryColumns.length, 1); - t.is(primaryColumns[0].column_name, "id"); - t.is(primaryColumns[0].data_type, "integer"); + t.is(primaryColumns[0].column_name, 'id'); + t.is(primaryColumns[0].data_type, 'integer'); t.is(readonly_fields.length, 0); t.is(table_widgets.length, 0); t.is(foreignKeys.length, 0); @@ -1848,144 +1568,113 @@ test.serial(`${currentTest} should return table structure`, async (t) => { } }); -test.serial( - `${currentTest} should throw an exception when connection id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const getTablesStructure = await request(app.getHttpServer()) - .get(`/table/structure/?tableName=${firstTableInfo.testTableName}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 404); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 404); + } catch (e) { + console.error(e); + throw e; + } +}); - const fakeConnectionId = faker.string.uuid(); - const getTablesStructure = await request(app.getHttpServer()) - .get( - `/table/structure/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 403); - const getTablesStructureRO = JSON.parse(getTablesStructure.text); - t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; -test.serial( - `${currentTest} should throw an exception when table name not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesStructure = await request(app.getHttpServer()) - .get(`/table/structure/${connections.firstId}?tableName=`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 400); - const getTablesStructureRO = JSON.parse(getTablesStructure.text); - t.is(getTablesStructureRO.message, Messages.TABLE_NAME_MISSING); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const fakeConnectionId = faker.string.uuid(); + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 403); + const getTablesStructureRO = JSON.parse(getTablesStructure.text); + t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTablesStructure = await request(app.getHttpServer()) - .get( - `/table/structure/${connections.firstId}?tableName=${fakeTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 403); - const getTablesStructureRO = JSON.parse(getTablesStructure.text); - t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when table name not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${connections.firstId}?tableName=`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 400); + const getTablesStructureRO = JSON.parse(getTablesStructure.text); + t.is(getTablesStructureRO.message, Messages.TABLE_NAME_MISSING); + } catch (e) { + console.error(e); + throw e; + } +}); + +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${connections.firstId}?tableName=${fakeTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 403); + const getTablesStructureRO = JSON.parse(getTablesStructure.text); + t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "POST /table/row/:slug"; +currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should return added row`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -2001,132 +1690,110 @@ test.serial(`${currentTest} should return added row`, async (t) => { const created_at = new Date(); const updated_at = new Date(); const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) + .post(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) .send({ [firstTableInfo.testTableColumnName]: randomName, [firstTableInfo.testTableSecondColumnName]: randomEmail, created_at: created_at, updated_at: updated_at, }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const addRowInTableRO = JSON.parse(addRowInTable.text); t.is(addRowInTable.status, 201); - t.is(Object.hasOwn(addRowInTableRO.row, "id"), true); + t.is(Object.hasOwn(addRowInTableRO.row, 'id'), true); t.is(addRowInTableRO.row[firstTableInfo.testTableColumnName], randomName); - t.is( - addRowInTableRO.row[firstTableInfo.testTableSecondColumnName], - randomEmail, - ); - t.is(Object.hasOwn(addRowInTableRO.row, "created_at"), true); - t.is(Object.hasOwn(addRowInTableRO.row, "updated_at"), true); - t.is(Object.hasOwn(addRowInTableRO, "structure"), true); - t.is(Object.hasOwn(addRowInTableRO, "foreignKeys"), true); - t.is(Object.hasOwn(addRowInTableRO, "primaryColumns"), true); - t.is(Object.hasOwn(addRowInTableRO, "readonly_fields"), true); + t.is(addRowInTableRO.row[firstTableInfo.testTableSecondColumnName], randomEmail); + t.is(Object.hasOwn(addRowInTableRO.row, 'created_at'), true); + t.is(Object.hasOwn(addRowInTableRO.row, 'updated_at'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); } catch (e) { console.error(e); throw e; } }); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const fakeConnectionId = faker.string.uuid(); - const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`, - ) - .send({ - [firstTableInfo.testTableColumnName]: randomName, - [firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeConnectionId = faker.string.uuid(); + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`) + .send({ + [firstTableInfo.testTableColumnName]: randomName, + [firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTable = await request(app.getHttpServer()) - .post(`/table/row/${connections.firstId}?tableName=${fakeTableName}`) - .send({ - [firstTableInfo.testTableColumnName]: randomName, - [firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${connections.firstId}?tableName=${fakeTableName}`) + .send({ + [firstTableInfo.testTableColumnName]: randomName, + [firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "PUT /table/row/:slug"; +currentTest = 'PUT /table/row/:slug'; test.serial( `${currentTest} should throw an exception do not have permission, when you do not have edit permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -2141,18 +1808,16 @@ test.serial( const created_at = new Date(); const updated_at = new Date(); const updateRowInTable = await request(app.getHttpServer()) - .put( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=2`, - ) + .put(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=2`) .send({ name: randomName, email: randomEmail, created_at: created_at, updated_at: updated_at, }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const addRowInTableRO = JSON.parse(updateRowInTable.text); t.is(updateRowInTable.status, 403); t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); @@ -2163,100 +1828,105 @@ test.serial( }, ); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const fakeConnectionId = faker.string.uuid(); - const addRowInTable = await request(app.getHttpServer()) - .put( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`, - ) - .send({ - name: randomName, - email: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeConnectionId = faker.string.uuid(); + const addRowInTable = await request(app.getHttpServer()) + .put(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`) + .send({ + name: randomName, + email: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTable = await request(app.getHttpServer()) - .put( - `/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`, - ) - .send({ - name: randomName, - email: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTable = await request(app.getHttpServer()) + .put(`/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`) + .send({ + name: randomName, + email: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "DELETE /table/row/:slug"; +currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should return delete result`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const deleteRowInTable = await request(app.getHttpServer()) + .delete(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=19`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTable.status, 200); + } catch (e) { + console.error(e); + throw e; + } +}); + +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -2265,96 +1935,51 @@ test.serial(`${currentTest} should return delete result`, async (t) => { secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; + const fakeConnectionId = faker.string.uuid(); const deleteRowInTable = await request(app.getHttpServer()) - .delete( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=19`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(deleteRowInTable.status, 200); + .delete(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteRowInTableRO = JSON.parse(deleteRowInTable.text); + t.is(deleteRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + t.is(deleteRowInTable.status, 403); } catch (e) { console.error(e); throw e; } }); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeConnectionId = faker.string.uuid(); - const deleteRowInTable = await request(app.getHttpServer()) - .delete( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteRowInTableRO = JSON.parse(deleteRowInTable.text); - t.is(deleteRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - t.is(deleteRowInTable.status, 403); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTable = await request(app.getHttpServer()) - .delete( - `/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteRowInTabbleRO = JSON.parse(deleteRowInTable.text); - t.is(deleteRowInTabbleRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTable = await request(app.getHttpServer()) + .delete(`/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteRowInTabbleRO = JSON.parse(deleteRowInTable.text); + t.is(deleteRowInTabbleRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "GET /table/row/:slug"; +currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} should return row`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -2364,167 +1989,135 @@ test.serial(`${currentTest} should return row`, async (t) => { users: { adminUserToken, simpleUserToken }, } = testData; const getRowInTable = await request(app.getHttpServer()) - .get( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=7`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=7`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getRowInTableRO = JSON.parse(getRowInTable.text); t.is(getRowInTable.status, 200); t.is(getRowInTableRO.row.id, 7); - t.is(Object.hasOwn(getRowInTableRO.row, "created_at"), true); - t.is(Object.hasOwn(getRowInTableRO.row, "updated_at"), true); - t.is(Object.hasOwn(getRowInTableRO, "structure"), true); - t.is(Object.hasOwn(getRowInTableRO, "foreignKeys"), true); - t.is(Object.hasOwn(getRowInTableRO, "primaryColumns"), true); - t.is(Object.hasOwn(getRowInTableRO, "readonly_fields"), true); + t.is(Object.hasOwn(getRowInTableRO.row, 'created_at'), true); + t.is(Object.hasOwn(getRowInTableRO.row, 'updated_at'), true); + t.is(Object.hasOwn(getRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(getRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(getRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getRowInTableRO, 'readonly_fields'), true); } catch (e) { console.error(e); throw e; } }); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeConnectionId = faker.string.uuid(); - const addRowInTable = await request(app.getHttpServer()) - .get( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=5`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeConnectionId = faker.string.uuid(); + const addRowInTable = await request(app.getHttpServer()) + .get(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=5`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTable = await request(app.getHttpServer()) - .get( - `/table/row/${connections.firstId}?tableName=${fakeTableName}&id=5`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTable = await request(app.getHttpServer()) + .get(`/table/row/${connections.firstId}?tableName=${fakeTableName}&id=5`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); //****************************** TABLE LOGS CONTROLLER TESTS ******************************// -currentTest = "GET /logs/:slug"; - -test.serial( - `${currentTest} should return all found logs in connection'`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .send({ - [firstTableInfo.testTableColumnName]: randomName, - [firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(addRowInTable.status, 201); +currentTest = 'GET /logs/:slug'; - const getTableLogs = await request(app.getHttpServer()) - .get(`/logs/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getRowInTableRO = JSON.parse(getTableLogs.text); +test.serial(`${currentTest} should return all found logs in connection'`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .send({ + [firstTableInfo.testTableColumnName]: randomName, + [firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTable.status, 201); - t.is(getRowInTableRO.logs.length, 1); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "table_name"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "received_data"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "old_data"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "cognitoUserName"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "email"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "operationType"), true); - t.is( - Object.hasOwn(getRowInTableRO.logs[0], "operationStatusResult"), - true, - ); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "createdAt"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "connection_id"), true); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const getTableLogs = await request(app.getHttpServer()) + .get(`/logs/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getRowInTableRO = JSON.parse(getTableLogs.text); + + t.is(getRowInTableRO.logs.length, 1); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'table_name'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'received_data'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'old_data'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'cognitoUserName'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'email'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'operationType'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'operationStatusResult'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'createdAt'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'connection_id'), true); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should not return all found logs in connection, when table audit is disabled in connection'`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -2538,61 +2131,53 @@ test.serial( const created_at = new Date(); const updated_at = new Date(); - const updateConnection = - mockFactory.generateConnectionToTestPostgresDBInDocker(); + const updateConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); const updateConnectionResponse = await request(app.getHttpServer()) .put(`/connection/${connections.firstId}`) .send(updateConnection) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(updateConnectionResponse.status, 200); - const newConnectionProperties = - mockFactory.generateConnectionPropertiesUserExcluded( - firstTableInfo.testTableName, - false, - ); + const newConnectionProperties = mockFactory.generateConnectionPropertiesUserExcluded( + firstTableInfo.testTableName, + false, + ); newConnectionProperties.hidden_tables = []; newConnectionProperties.tables_audit = false; - const createConnectionPropertiesResponse = await request( - app.getHttpServer(), - ) + const createConnectionPropertiesResponse = await request(app.getHttpServer()) .post(`/connection/properties/${connections.firstId}`) .send(newConnectionProperties) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const _connectionPropertiesResult = JSON.parse( - createConnectionPropertiesResponse.text, - ); + const _connectionPropertiesResult = JSON.parse(createConnectionPropertiesResponse.text); t.is(createConnectionPropertiesResponse.status, 201); const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) + .post(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) .send({ [firstTableInfo.testTableColumnName]: randomName, [firstTableInfo.testTableSecondColumnName]: randomEmail, created_at: created_at, updated_at: updated_at, }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(addRowInTable.status, 201); const getTableLogs = await request(app.getHttpServer()) .get(`/logs/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getRowInTableRO = JSON.parse(getTableLogs.text); t.is(getRowInTableRO.logs.length, 0); @@ -2605,49 +2190,13 @@ test.serial( //****************************** TABLE SETTINGS CONTROLLER TESTS ******************************// -currentTest = "GET /settings/"; +currentTest = 'GET /settings/'; test.serial( `${currentTest} should exception ${Messages.DONT_HAVE_PERMISSIONS} when table settings was not created`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTableSettings = await request(app.getHttpServer()) - .get( - `/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getTableSettingsRO = JSON.parse(getTableSettings.text); - t.is(getTableSettings.status, 403); - t.is(getTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} 'should should throw exception ${Messages.DONT_HAVE_PERMISSIONS}`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -2656,36 +2205,11 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - ['id'], - [firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); - const getTableSettings = await request(app.getHttpServer()) - .get( - `/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getTableSettingsRO = JSON.parse(getTableSettings.text); t.is(getTableSettings.status, 403); t.is(getTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); @@ -2696,73 +2220,57 @@ test.serial( }, ); -test.serial( - `${currentTest} should throw an exception when you try get settings in connection where you do not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(createTableSettingsResponse.status, 201); +test.serial(`${currentTest} 'should should throw exception ${Messages.DONT_HAVE_PERMISSIONS}`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const getTableSettings = await request(app.getHttpServer()) - .get( - `/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getTableSettingsRO = JSON.parse(getTableSettings.text); - t.is(getTableSettings.status, 403); - t.is(getTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + ['id'], + [firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); -currentTest = "POST /settings/"; + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableSettings = await request(app.getHttpServer()) + .get(`/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getTableSettingsRO = JSON.parse(getTableSettings.text); + t.is(getTableSettings.status, 403); + t.is(getTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( - `${currentTest} should throw an exception do not have permission`, + `${currentTest} should throw an exception when you try get settings in connection where you do not have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -2772,31 +2280,35 @@ test.serial( users: { adminUserToken, simpleUserToken }, } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - 'users', - ['id'], - ['email'], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`, - ) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) .send(createTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 403); - t.is( - JSON.parse(createTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const getTableSettings = await request(app.getHttpServer()) + .get(`/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getTableSettingsRO = JSON.parse(getTableSettings.text); + t.is(getTableSettings.status, 403); + t.is(getTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -2804,14 +2316,51 @@ test.serial( }, ); +currentTest = 'POST /settings/'; + +test.serial(`${currentTest} should throw an exception do not have permission`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + 'users', + ['id'], + ['email'], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`) + .send(createTableSettingsDTO) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 403); + t.is(JSON.parse(createTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); + test.serial( `${currentTest} should throw an exception when you try create settings in connection where you do not have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -2821,31 +2370,27 @@ test.serial( users: { adminUserToken, simpleUserToken }, } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}`, - ) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}`) .send(createTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createTableSettingsResponse.status, 403); - const createTableSettingsRO = JSON.parse( - createTableSettingsResponse.text, - ); + const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); t.is(createTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); @@ -2854,133 +2399,118 @@ test.serial( }, ); -currentTest = "PUT /settings/"; +currentTest = 'PUT /settings/'; test.serial(`${currentTest} should throw an exception do not have permission`, async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - ['id'], - [firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + ['id'], + [firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); - const updateTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - [firstTableInfo.testTableSecondColumnName], - ['id'], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const updateTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + [firstTableInfo.testTableSecondColumnName], + ['id'], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); - const updateTableSettingsResponse = await request(app.getHttpServer()) - .put( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`, - ) - .send(updateTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(updateTableSettingsResponse.status, 403); - t.is( - JSON.parse(updateTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const updateTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`) + .send(updateTableSettingsDTO) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(updateTableSettingsResponse.status, 403); + t.is(JSON.parse(updateTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( - `${currentTest} should throw an exception when you try update settings in connection where you do not have permission`, - async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + `${currentTest} should throw an exception when you try update settings in connection where you do not have permission`, + async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createTableSettingsResponse.status, 201); - const updateTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - [firstTableInfo.testTableSecondColumnName], - ['id'], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const updateTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + [firstTableInfo.testTableSecondColumnName], + ['id'], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); const updateTableSettingsResponse = await request(app.getHttpServer()) - .put( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}}`, - ) + .put(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}}`) .send(updateTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(updateTableSettingsResponse.status, 403); - t.is( - JSON.parse(updateTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + t.is(JSON.parse(updateTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -2988,127 +2518,58 @@ test.serial( }, ); -currentTest = "DELETE /settings/"; +currentTest = 'DELETE /settings/'; test.serial(`${currentTest} should return array without deleted table settings`, async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - ['id'], - [firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); - - const deleteTableSettingsResponse = await request(app.getHttpServer()) - .delete( - `/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(deleteTableSettingsResponse.status, 403); - t.is( - JSON.parse(deleteTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw an exception when you try delete settings in connection where you do not have permission`, - async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); - - const deleteTableSettingsResponse = await request(app.getHttpServer()) - .delete( - `/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteTableSettingsRO = JSON.parse( - deleteTableSettingsResponse.text, - ); - t.is(deleteTableSettingsResponse.status, 403); - t.is(deleteTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -//****************************** TABLE WIDGETS CONTROLLER TESTS ******************************// + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + ['id'], + [firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); -currentTest = "GET /widgets/:slug"; + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const deleteTableSettingsResponse = await request(app.getHttpServer()) + .delete(`/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteTableSettingsResponse.status, 403); + t.is(JSON.parse(deleteTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( - `${currentTest} should return empty widgets array when widgets not created`, + `${currentTest} should throw an exception when you try delete settings in connection where you do not have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -3117,16 +2578,34 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const getTableWidgets = await request(app.getHttpServer()) - .get( - `/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(getTableWidgets.status, 403); - t.is(getTableWidgetsRO.message, Messages.DONT_HAVE_PERMISSIONS); + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const deleteTableSettingsResponse = await request(app.getHttpServer()) + .delete(`/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteTableSettingsRO = JSON.parse(deleteTableSettingsResponse.text); + t.is(deleteTableSettingsResponse.status, 403); + t.is(deleteTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -3134,100 +2613,99 @@ test.serial( }, ); -test.serial( - `${currentTest} should return array of table widgets for table`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +//****************************** TABLE WIDGETS CONTROLLER TESTS ******************************// - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); - const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", adminUserToken) - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 201); - t.is(typeof createTableWidgetRO, "object"); - t.is(createTableWidgetRO.length, 2); - t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); - t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); - t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); +currentTest = 'GET /widgets/:slug'; - const getTableWidgets = await request(app.getHttpServer()) - .get( - `/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - t.is(getTableWidgets.status, 403); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(getTableWidgetsRO.message, Messages.DONT_HAVE_PERMISSIONS); +test.serial(`${currentTest} should return empty widgets array when widgets not created`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(getTableWidgets.status, 403); + t.is(getTableWidgetsRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); - const getTableStructureResponse = await request(app.getHttpServer()) - .get( - `/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - t.is(getTableStructureResponse.status, 200); - const getTableStructureRO = JSON.parse(getTableStructureResponse.text); - t.is(Object.hasOwn(getTableStructureRO, "table_widgets"), true); - t.is(getTableStructureRO.table_widgets.length, 2); - getTableStructureRO.table_widgets.sort((a, b) => - a.field_name.localeCompare(b.field_name), - ); - newTableWidgets.sort((a, b) => a.field_name.localeCompare(b.field_name)); - t.is( - getTableStructureRO.table_widgets[0].field_name, - newTableWidgets[0].field_name, - ); - t.is( - getTableStructureRO.table_widgets[1].widget_type, - newTableWidgets[1].widget_type, - ); - t.is( - compareTableWidgetsArrays( - getTableStructureRO.table_widgets, - newTableWidgets, - ), - true, - ); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should return array of table widgets for table`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', adminUserToken) + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 201); + t.is(typeof createTableWidgetRO, 'object'); + t.is(createTableWidgetRO.length, 2); + t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); + t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); + t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); + + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + t.is(getTableWidgets.status, 403); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(getTableWidgetsRO.message, Messages.DONT_HAVE_PERMISSIONS); + + const getTableStructureResponse = await request(app.getHttpServer()) + .get(`/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + t.is(getTableStructureResponse.status, 200); + const getTableStructureRO = JSON.parse(getTableStructureResponse.text); + t.is(Object.hasOwn(getTableStructureRO, 'table_widgets'), true); + t.is(getTableStructureRO.table_widgets.length, 2); + getTableStructureRO.table_widgets.sort((a, b) => a.field_name.localeCompare(b.field_name)); + newTableWidgets.sort((a, b) => a.field_name.localeCompare(b.field_name)); + t.is(getTableStructureRO.table_widgets[0].field_name, newTableWidgets[0].field_name); + t.is(getTableStructureRO.table_widgets[1].widget_type, newTableWidgets[1].widget_type); + t.is(compareTableWidgetsArrays(getTableStructureRO.table_widgets, newTableWidgets), true); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception, when you try to get widgets from connection, when you do not have permissions`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -3236,31 +2714,26 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) + .post(`/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", adminUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', adminUserToken) + .set('Accept', 'application/json'); const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 201); - t.is(typeof createTableWidgetRO, "object"); + t.is(typeof createTableWidgetRO, 'object'); t.is(createTableWidgetRO.length, 2); const getTableWidgets = await request(app.getHttpServer()) - .get( - `/widgets/${connections.secondId}?tableName=${secondTableInfo.testTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .get(`/widgets/${connections.secondId}?tableName=${secondTableInfo.testTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); const getTableWidgetsRO = JSON.parse(getTableWidgets.text); t.is(getTableWidgets.status, 403); t.is(getTableWidgetsRO.message, Messages.DONT_HAVE_PERMISSIONS); @@ -3271,57 +2744,45 @@ test.serial( }, ); -currentTest = "POST /widget/:slug"; +currentTest = 'POST /widget/:slug'; -test.serial( - `${currentTest} should throw an exception do not have permissions`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw an exception do not have permissions`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); - const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}}`, - ) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 403); - t.is(createTableWidgetRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 403); + t.is(createTableWidgetRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception, when you try add widget in connection, when you do not have permissions`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -3330,20 +2791,17 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.secondId}?tableName=${secondTableInfo.testTableName}`, - ) + .post(`/widget/${connections.secondId}?tableName=${secondTableInfo.testTableName}`) .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 403); t.is(createTableWidgetRO.message, Messages.DONT_HAVE_PERMISSIONS); diff --git a/backend/test/ava-tests/saas-tests/ai-chat-e2e.test.ts b/backend/test/ava-tests/saas-tests/ai-chat-e2e.test.ts index 99727dc9b..b33a2e74e 100644 --- a/backend/test/ava-tests/saas-tests/ai-chat-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/ai-chat-e2e.test.ts @@ -89,7 +89,6 @@ test.after(async () => { } }); - currentTest = 'GET /ai/chats'; test.serial(`${currentTest} should return empty list when user has no chats`, async (t) => { @@ -416,7 +415,6 @@ test.serial(`${currentTest} should not allow deleting another user's chat`, asyn } }); - currentTest = 'POST /ai/v4/request/:connectionId'; test.serial(`${currentTest} should create AI request and save conversation history`, async (t) => { diff --git a/backend/test/ava-tests/saas-tests/api-key-e2e.test.ts b/backend/test/ava-tests/saas-tests/api-key-e2e.test.ts index eaeac49e8..242841552 100644 --- a/backend/test/ava-tests/saas-tests/api-key-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/api-key-e2e.test.ts @@ -26,339 +26,339 @@ let currentTest: string; const mockFactory = new MockFactory(); test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - // testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + // testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After custom field error: ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After custom field error: ' + e); + } }); currentTest = `POST /apikey`; test.serial(`${currentTest} should return created api key for this user`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - const apiKeyTitle = 'Test API Key'; - - const createApiKeyResult = await request(app.getHttpServer()) - .post('/apikey') - .send({ title: apiKeyTitle }) - .set('Content-Type', 'application/json') - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - - t.is(createApiKeyResult.status, 201); - const createApiKeyRO = JSON.parse(createApiKeyResult.text); - t.is(createApiKeyRO.title, apiKeyTitle); - t.truthy(createApiKeyRO.hash); - t.truthy(createApiKeyRO.hash.includes('sk_')); - t.truthy(createApiKeyRO.id); - - // check that user has access to table controller - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json') - .set('x-api-key', createApiKeyRO.hash); - - const getTablesRO = JSON.parse(getTablesResponse.text); - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.length > 0, true); - - const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); - - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); - t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); - t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); - t.is(getTablesRO[testTableIndex].table, testTableName); - t.is(getTablesRO[testTableIndex].permissions.visibility, true); - t.is(getTablesRO[testTableIndex].permissions.readonly, false); - t.is(getTablesRO[testTableIndex].permissions.add, true); - t.is(getTablesRO[testTableIndex].permissions.delete, true); - t.is(getTablesRO[testTableIndex].permissions.edit, true); - } catch (error) { - console.error(error); - throw error; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + const apiKeyTitle = 'Test API Key'; + + const createApiKeyResult = await request(app.getHttpServer()) + .post('/apikey') + .send({ title: apiKeyTitle }) + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + + t.is(createApiKeyResult.status, 201); + const createApiKeyRO = JSON.parse(createApiKeyResult.text); + t.is(createApiKeyRO.title, apiKeyTitle); + t.truthy(createApiKeyRO.hash); + t.truthy(createApiKeyRO.hash.includes('sk_')); + t.truthy(createApiKeyRO.id); + + // check that user has access to table controller + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json') + .set('x-api-key', createApiKeyRO.hash); + + const getTablesRO = JSON.parse(getTablesResponse.text); + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.length > 0, true); + + const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); + + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); + t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); + t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); + t.is(getTablesRO[testTableIndex].table, testTableName); + t.is(getTablesRO[testTableIndex].permissions.visibility, true); + t.is(getTablesRO[testTableIndex].permissions.readonly, false); + t.is(getTablesRO[testTableIndex].permissions.add, true); + t.is(getTablesRO[testTableIndex].permissions.delete, true); + t.is(getTablesRO[testTableIndex].permissions.edit, true); + } catch (error) { + console.error(error); + throw error; + } }); test.serial(`${currentTest} user should have access to table controller by api key`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token } = adminUserRegisterInfo; - - const apiKeyTitle = 'Test API Key'; - - const createApiKeyResult = await request(app.getHttpServer()) - .post('/apikey') - .send({ title: apiKeyTitle }) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(createApiKeyResult.status, 201); - const createApiKeyRO = JSON.parse(createApiKeyResult.text); - t.is(createApiKeyRO.title, apiKeyTitle); - t.truthy(createApiKeyRO.hash); - t.truthy(createApiKeyRO.hash.includes('sk_')); - t.truthy(createApiKeyRO.id); - } catch (error) { - console.error(error); - throw error; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token } = adminUserRegisterInfo; + + const apiKeyTitle = 'Test API Key'; + + const createApiKeyResult = await request(app.getHttpServer()) + .post('/apikey') + .send({ title: apiKeyTitle }) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(createApiKeyResult.status, 201); + const createApiKeyRO = JSON.parse(createApiKeyResult.text); + t.is(createApiKeyRO.title, apiKeyTitle); + t.truthy(createApiKeyRO.hash); + t.truthy(createApiKeyRO.hash.includes('sk_')); + t.truthy(createApiKeyRO.id); + } catch (error) { + console.error(error); + throw error; + } }); test.serial(`${currentTest} should throw an exception when title not passed`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token } = adminUserRegisterInfo; - - const createApiKeyResult = await request(app.getHttpServer()) - .post('/apikey') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(createApiKeyResult.status, 400); - const createApiKeyRO = JSON.parse(createApiKeyResult.text); - t.truthy(createApiKeyRO.message.includes(`Property "title" validation failed`)); - } catch (error) { - console.error(error); - throw error; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token } = adminUserRegisterInfo; + + const createApiKeyResult = await request(app.getHttpServer()) + .post('/apikey') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(createApiKeyResult.status, 400); + const createApiKeyRO = JSON.parse(createApiKeyResult.text); + t.truthy(createApiKeyRO.message.includes(`Property "title" validation failed`)); + } catch (error) { + console.error(error); + throw error; + } }); currentTest = `GET /apikeys`; test.serial(`${currentTest} should return all users api keys`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token } = adminUserRegisterInfo; - - const apiKeysData = [{ title: 'Test API Key 1' }, { title: 'Test API Key 2' }, { title: 'Test API Key 3' }]; - - for (const apiKeyData of apiKeysData) { - const createApiKeyResult = await request(app.getHttpServer()) - .post('/apikey') - .send(apiKeyData) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - t.is(createApiKeyResult.status, 201); - } - - const getApiKeysResult = await request(app.getHttpServer()) - .get('/apikeys') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getApiKeysResult.status, 200); - const getApiKeysRO = JSON.parse(getApiKeysResult.text); - t.is(getApiKeysRO.length, apiKeysData.length); - - for (let i = 0; i < apiKeysData.length; i++) { - t.is(getApiKeysRO[i].title, apiKeysData[i].title); - t.falsy(getApiKeysRO[i].hash); - t.truthy(getApiKeysRO[i].id); - } - } catch (error) { - console.error(error); - throw error; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token } = adminUserRegisterInfo; + + const apiKeysData = [{ title: 'Test API Key 1' }, { title: 'Test API Key 2' }, { title: 'Test API Key 3' }]; + + for (const apiKeyData of apiKeysData) { + const createApiKeyResult = await request(app.getHttpServer()) + .post('/apikey') + .send(apiKeyData) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + t.is(createApiKeyResult.status, 201); + } + + const getApiKeysResult = await request(app.getHttpServer()) + .get('/apikeys') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getApiKeysResult.status, 200); + const getApiKeysRO = JSON.parse(getApiKeysResult.text); + t.is(getApiKeysRO.length, apiKeysData.length); + + for (let i = 0; i < apiKeysData.length; i++) { + t.is(getApiKeysRO[i].title, apiKeysData[i].title); + t.falsy(getApiKeysRO[i].hash); + t.truthy(getApiKeysRO[i].id); + } + } catch (error) { + console.error(error); + throw error; + } }); currentTest = `GET /apikey/:apiKeyId`; test.serial(`${currentTest} should return found user api key`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token } = adminUserRegisterInfo; - - const apiKeysData = [{ title: 'Test API Key 1' }, { title: 'Test API Key 2' }, { title: 'Test API Key 3' }]; - - const createdApiKeys = []; - for (const apiKeyData of apiKeysData) { - const createApiKeyResult = await request(app.getHttpServer()) - .post('/apikey') - .send(apiKeyData) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - t.is(createApiKeyResult.status, 201); - createdApiKeys.push(JSON.parse(createApiKeyResult.text)); - } - - const apiKeyToSearch = createdApiKeys[Math.floor(Math.random() * createdApiKeys.length)]; - - const getApiKeyResult = await request(app.getHttpServer()) - .get(`/apikey/${apiKeyToSearch.id}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getApiKeyResult.status, 200); - const getApiKeyRO = JSON.parse(getApiKeyResult.text); - t.is(getApiKeyRO.title, apiKeyToSearch.title); - t.falsy(getApiKeyRO.hash); - t.is(getApiKeyRO.id, apiKeyToSearch.id); - } catch (error) { - console.error(error); - throw error; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token } = adminUserRegisterInfo; + + const apiKeysData = [{ title: 'Test API Key 1' }, { title: 'Test API Key 2' }, { title: 'Test API Key 3' }]; + + const createdApiKeys = []; + for (const apiKeyData of apiKeysData) { + const createApiKeyResult = await request(app.getHttpServer()) + .post('/apikey') + .send(apiKeyData) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + t.is(createApiKeyResult.status, 201); + createdApiKeys.push(JSON.parse(createApiKeyResult.text)); + } + + const apiKeyToSearch = createdApiKeys[Math.floor(Math.random() * createdApiKeys.length)]; + + const getApiKeyResult = await request(app.getHttpServer()) + .get(`/apikey/${apiKeyToSearch.id}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getApiKeyResult.status, 200); + const getApiKeyRO = JSON.parse(getApiKeyResult.text); + t.is(getApiKeyRO.title, apiKeyToSearch.title); + t.falsy(getApiKeyRO.hash); + t.is(getApiKeyRO.id, apiKeyToSearch.id); + } catch (error) { + console.error(error); + throw error; + } }); test.serial(`${currentTest} should throw an exception when key with id not exist in database`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token } = adminUserRegisterInfo; - - const apiKeysData = [{ title: 'Test API Key 1' }, { title: 'Test API Key 2' }, { title: 'Test API Key 3' }]; - - const createdApiKeys = []; - for (const apiKeyData of apiKeysData) { - const createApiKeyResult = await request(app.getHttpServer()) - .post('/apikey') - .send(apiKeyData) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - t.is(createApiKeyResult.status, 201); - createdApiKeys.push(JSON.parse(createApiKeyResult.text)); - } - - const apiKeyToSearch = faker.string.uuid(); - - const getApiKeyResult = await request(app.getHttpServer()) - .get(`/apikey/${apiKeyToSearch}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getApiKeyResult.status, 404); - const getApiKeyRO = JSON.parse(getApiKeyResult.text); - t.is(getApiKeyRO.message, Messages.API_KEY_NOT_FOUND); - } catch (error) { - console.error(error); - throw error; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token } = adminUserRegisterInfo; + + const apiKeysData = [{ title: 'Test API Key 1' }, { title: 'Test API Key 2' }, { title: 'Test API Key 3' }]; + + const createdApiKeys = []; + for (const apiKeyData of apiKeysData) { + const createApiKeyResult = await request(app.getHttpServer()) + .post('/apikey') + .send(apiKeyData) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + t.is(createApiKeyResult.status, 201); + createdApiKeys.push(JSON.parse(createApiKeyResult.text)); + } + + const apiKeyToSearch = faker.string.uuid(); + + const getApiKeyResult = await request(app.getHttpServer()) + .get(`/apikey/${apiKeyToSearch}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getApiKeyResult.status, 404); + const getApiKeyRO = JSON.parse(getApiKeyResult.text); + t.is(getApiKeyRO.message, Messages.API_KEY_NOT_FOUND); + } catch (error) { + console.error(error); + throw error; + } }); test.serial(`${currentTest} should delete api key and return deleted key`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token } = adminUserRegisterInfo; - - const apiKeysData = [{ title: 'Test API Key 1' }, { title: 'Test API Key 2' }, { title: 'Test API Key 3' }]; - - const createdApiKeys = []; - for (const apiKeyData of apiKeysData) { - const createApiKeyResult = await request(app.getHttpServer()) - .post('/apikey') - .send(apiKeyData) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - t.is(createApiKeyResult.status, 201); - createdApiKeys.push(JSON.parse(createApiKeyResult.text)); - } - - const apiKeyToDeletion = createdApiKeys[Math.floor(Math.random() * createdApiKeys.length)]; - - const deleteApiKeyResult = await request(app.getHttpServer()) - .delete(`/apikey/${apiKeyToDeletion.id}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteApiKeyResult.status, 200); - const deleteApiKeyRO = JSON.parse(deleteApiKeyResult.text); - t.is(deleteApiKeyRO.title, apiKeyToDeletion.title); - t.falsy(deleteApiKeyRO.hash); - t.is(deleteApiKeyRO.id, apiKeyToDeletion.id); - - // check that key is deleted - - const getApiKeyResult = await request(app.getHttpServer()) - .get(`/apikey/${apiKeyToDeletion.id}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getApiKeyResult.status, 404); - const getApiKeyRO = JSON.parse(getApiKeyResult.text); - t.is(getApiKeyRO.message, Messages.API_KEY_NOT_FOUND); - } catch (error) { - console.error(error); - throw error; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token } = adminUserRegisterInfo; + + const apiKeysData = [{ title: 'Test API Key 1' }, { title: 'Test API Key 2' }, { title: 'Test API Key 3' }]; + + const createdApiKeys = []; + for (const apiKeyData of apiKeysData) { + const createApiKeyResult = await request(app.getHttpServer()) + .post('/apikey') + .send(apiKeyData) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + t.is(createApiKeyResult.status, 201); + createdApiKeys.push(JSON.parse(createApiKeyResult.text)); + } + + const apiKeyToDeletion = createdApiKeys[Math.floor(Math.random() * createdApiKeys.length)]; + + const deleteApiKeyResult = await request(app.getHttpServer()) + .delete(`/apikey/${apiKeyToDeletion.id}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteApiKeyResult.status, 200); + const deleteApiKeyRO = JSON.parse(deleteApiKeyResult.text); + t.is(deleteApiKeyRO.title, apiKeyToDeletion.title); + t.falsy(deleteApiKeyRO.hash); + t.is(deleteApiKeyRO.id, apiKeyToDeletion.id); + + // check that key is deleted + + const getApiKeyResult = await request(app.getHttpServer()) + .get(`/apikey/${apiKeyToDeletion.id}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getApiKeyResult.status, 404); + const getApiKeyRO = JSON.parse(getApiKeyResult.text); + t.is(getApiKeyRO.message, Messages.API_KEY_NOT_FOUND); + } catch (error) { + console.error(error); + throw error; + } }); currentTest = `GET /check/apikey`; test.serial(`${currentTest} should return created api key for this user`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const apiKeyTitle = 'Test API Key'; - - const createApiKeyResult = await request(app.getHttpServer()) - .post('/apikey') - .send({ title: apiKeyTitle }) - .set('Content-Type', 'application/json') - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - - t.is(createApiKeyResult.status, 201); - const createApiKeyRO = JSON.parse(createApiKeyResult.text); - t.is(createApiKeyRO.title, apiKeyTitle); - t.truthy(createApiKeyRO.hash); - t.truthy(createApiKeyRO.hash.includes('sk_')); - t.truthy(createApiKeyRO.id); - - const checkApiKeyResponse = await request(app.getHttpServer()) - .get(`/check/apikey`) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json') - .set('x-api-key', createApiKeyRO.hash); - t.is(checkApiKeyResponse.status, 200); - } catch (error) { - console.error(error); - throw error; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const apiKeyTitle = 'Test API Key'; + + const createApiKeyResult = await request(app.getHttpServer()) + .post('/apikey') + .send({ title: apiKeyTitle }) + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + + t.is(createApiKeyResult.status, 201); + const createApiKeyRO = JSON.parse(createApiKeyResult.text); + t.is(createApiKeyRO.title, apiKeyTitle); + t.truthy(createApiKeyRO.hash); + t.truthy(createApiKeyRO.hash.includes('sk_')); + t.truthy(createApiKeyRO.id); + + const checkApiKeyResponse = await request(app.getHttpServer()) + .get(`/check/apikey`) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json') + .set('x-api-key', createApiKeyRO.hash); + t.is(checkApiKeyResponse.status, 200); + } catch (error) { + console.error(error); + throw error; + } }); diff --git a/backend/test/ava-tests/saas-tests/app-e2e.test.ts b/backend/test/ava-tests/saas-tests/app-e2e.test.ts index cd0ae2da2..03c5e8107 100644 --- a/backend/test/ava-tests/saas-tests/app-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/app-e2e.test.ts @@ -11,22 +11,22 @@ import { Cacher } from '../../../src/helpers/cache/cacher.js'; let app: INestApplication; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService], - }).compile(); - app = moduleFixture.createNestApplication(); - await app.init(); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService], + }).compile(); + app = moduleFixture.createNestApplication(); + await app.init(); }); test.after(async () => { - await Cacher.clearAllCache(); - await app.close(); + await Cacher.clearAllCache(); + await app.close(); }); test.serial(' > get hello', async (t) => { - const result = await request(app.getHttpServer()).get('/hello'); - const responseText = result.text; - t.assert('Hello World!', responseText); - t.pass(); + const result = await request(app.getHttpServer()).get('/hello'); + const responseText = result.text; + t.assert('Hello World!', responseText); + t.pass(); }); diff --git a/backend/test/ava-tests/saas-tests/connection-e2e.test.ts b/backend/test/ava-tests/saas-tests/connection-e2e.test.ts index 9234d9066..5d477d071 100644 --- a/backend/test/ava-tests/saas-tests/connection-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/connection-e2e.test.ts @@ -16,8 +16,8 @@ import { DatabaseService } from '../../../src/shared/database/database.service.j import { MockFactory } from '../../mock.factory.js'; import { getTestData } from '../../utils/get-test-data.js'; import { - inviteUserInCompanyAndAcceptInvitation, - registerUserAndReturnUserInfo, + inviteUserInCompanyAndAcceptInvitation, + registerUserAndReturnUserInfo, } from '../../utils/register-user-and-return-user-info.js'; import { TestUtils } from '../../utils/test.utils.js'; import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; @@ -28,1841 +28,1797 @@ let _testUtils: TestUtils; let currentTest: string; type RegisterUserData = { - email: string; - password: string; + email: string; + password: string; }; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - _testUtils = moduleFixture.get(TestUtils); - - app = moduleFixture.createNestApplication() as any; - app.use(cookieParser()); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + _testUtils = moduleFixture.get(TestUtils); + + app = moduleFixture.createNestApplication() as any; + app.use(cookieParser()); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After custom field error: ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After custom field error: ' + e); + } }); function getTestConnectionData() { - const newConnection = mockFactory.generateCreateConnectionDto(); - const newConnection2 = mockFactory.generateCreateConnectionDto2(); - const newConnectionToTestDB = mockFactory.generateCreateConnectionDtoToTEstDB(); - const updateConnection = mockFactory.generateUpdateConnectionDto(); - const newGroup1 = mockFactory.generateCreateGroupDto1(); - return { - newConnection, - newConnection2, - newConnectionToTestDB, - updateConnection, - newGroup1, - }; + const newConnection = mockFactory.generateCreateConnectionDto(); + const newConnection2 = mockFactory.generateCreateConnectionDto2(); + const newConnectionToTestDB = mockFactory.generateCreateConnectionDtoToTEstDB(); + const updateConnection = mockFactory.generateUpdateConnectionDto(); + const newGroup1 = mockFactory.generateCreateGroupDto1(); + return { + newConnection, + newConnection2, + newConnectionToTestDB, + updateConnection, + newGroup1, + }; } currentTest = '> GET /connections >'; test.serial(`${currentTest} should return all connections for this user`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - const findAllConnectionsResponse = await request(app.getHttpServer()) - .get('/connections') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(findAllConnectionsResponse.status, 200); - t.is(findAllConnectionsResponse.body.connections.length, 4); - - let createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createConnectionResult.status, 201); - - createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createConnectionResult.status, 201); - - const findAll = await request(app.getHttpServer()) - .get('/connections') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(findAll.status, 200); - - const result = findAll.body.connections; - - t.is(result.length, 6); - t.is(Object.hasOwn(result[0], 'connection'), true); - t.is(Object.hasOwn(result[1], 'accessLevel'), true); - t.is(result[2].accessLevel, AccessLevelEnum.edit); - - t.is(Object.hasOwn(result[3], 'accessLevel'), true); - t.is(Object.hasOwn(result[4].connection, 'host'), true); - t.is(Object.hasOwn(result[3].connection, 'host'), true); - t.is(typeof result[0].connection.port, 'number'); - t.is(Object.hasOwn(result[2].connection, 'username'), true); - t.is(Object.hasOwn(result[3].connection, 'database'), true); - t.is(Object.hasOwn(result[0].connection, 'createdAt'), true); - t.is(Object.hasOwn(result[1].connection, 'updatedAt'), true); - t.is(Object.hasOwn(result[2].connection, 'password'), false); - t.is(Object.hasOwn(result[3].connection, 'groups'), false); - const oracleConnectionIndex = result.findIndex((e) => e.connection.type === ConnectionTypesEnum.oracledb); - // eslint-disable-next-line security/detect-object-injection - t.is(Object.hasOwn(result[oracleConnectionIndex].connection, 'sid'), true); - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + const findAllConnectionsResponse = await request(app.getHttpServer()) + .get('/connections') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(findAllConnectionsResponse.status, 200); + t.is(findAllConnectionsResponse.body.connections.length, 4); + + let createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createConnectionResult.status, 201); + + createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createConnectionResult.status, 201); + + const findAll = await request(app.getHttpServer()) + .get('/connections') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(findAll.status, 200); + + const result = findAll.body.connections; + + t.is(result.length, 6); + t.is(Object.hasOwn(result[0], 'connection'), true); + t.is(Object.hasOwn(result[1], 'accessLevel'), true); + t.is(result[2].accessLevel, AccessLevelEnum.edit); + + t.is(Object.hasOwn(result[3], 'accessLevel'), true); + t.is(Object.hasOwn(result[4].connection, 'host'), true); + t.is(Object.hasOwn(result[3].connection, 'host'), true); + t.is(typeof result[0].connection.port, 'number'); + t.is(Object.hasOwn(result[2].connection, 'username'), true); + t.is(Object.hasOwn(result[3].connection, 'database'), true); + t.is(Object.hasOwn(result[0].connection, 'createdAt'), true); + t.is(Object.hasOwn(result[1].connection, 'updatedAt'), true); + t.is(Object.hasOwn(result[2].connection, 'password'), false); + t.is(Object.hasOwn(result[3].connection, 'groups'), false); + const oracleConnectionIndex = result.findIndex((e) => e.connection.type === ConnectionTypesEnum.oracledb); + // eslint-disable-next-line security/detect-object-injection + t.is(Object.hasOwn(result[oracleConnectionIndex].connection, 'sid'), true); + t.pass(); }); currentTest = '> GET connection/users/:slug >'; test.serial(`${currentTest} should return all connection users`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createConnectionResponse.status, 201); - - const connectionRO = JSON.parse(createConnectionResponse.text); - - const findAllUsersResponse = await request(app.getHttpServer()) - .get(`/connection/users/${connectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(findAllUsersResponse.status, 200); - - const foundUsersRO = JSON.parse(findAllUsersResponse.text); - t.is(foundUsersRO.length, 1); - - t.is(foundUsersRO[0].isActive, false); - t.is(Object.hasOwn(foundUsersRO[0], 'createdAt'), true); - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createConnectionResponse.status, 201); + + const connectionRO = JSON.parse(createConnectionResponse.text); + + const findAllUsersResponse = await request(app.getHttpServer()) + .get(`/connection/users/${connectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(findAllUsersResponse.status, 200); + + const foundUsersRO = JSON.parse(findAllUsersResponse.text); + t.is(foundUsersRO.length, 1); + + t.is(foundUsersRO[0].isActive, false); + t.is(Object.hasOwn(foundUsersRO[0], 'createdAt'), true); + t.pass(); }); test.serial(`${currentTest} should return all connection users from different groups`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createConnectionResponse.status, 201); - - const connectionRO = JSON.parse(createConnectionResponse.text); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connectionRO.id}`) - .send(newGroup1) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createGroupResponse.status, 201); - const createGroupRO = JSON.parse(createGroupResponse.text); - - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation(token, undefined, app, undefined); - - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: createGroupRO.id, - }; - const addUserInGroupResponse = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroupResponse.status, 200); - - const findAllUsersResponse = await request(app.getHttpServer()) - .get(`/connection/users/${connectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(findAllUsersResponse.status, 200); - const foundUsersRO = JSON.parse(findAllUsersResponse.text); - t.is(foundUsersRO.length, 2); - - // t.is(foundUsersRO[0].isActive, false); - t.is(foundUsersRO[1].isActive, true); - t.is(Object.hasOwn(foundUsersRO[1], 'email'), true); - t.is(Object.hasOwn(foundUsersRO[0], 'email'), true); - t.is(Object.hasOwn(foundUsersRO[0], 'createdAt'), true); - t.is(Object.hasOwn(foundUsersRO[1], 'createdAt'), true); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createConnectionResponse.status, 201); + + const connectionRO = JSON.parse(createConnectionResponse.text); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connectionRO.id}`) + .send(newGroup1) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createGroupResponse.status, 201); + const createGroupRO = JSON.parse(createGroupResponse.text); + + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation(token, undefined, app, undefined); + + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: createGroupRO.id, + }; + const addUserInGroupResponse = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroupResponse.status, 200); + + const findAllUsersResponse = await request(app.getHttpServer()) + .get(`/connection/users/${connectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(findAllUsersResponse.status, 200); + const foundUsersRO = JSON.parse(findAllUsersResponse.text); + t.is(foundUsersRO.length, 2); + + // t.is(foundUsersRO[0].isActive, false); + t.is(foundUsersRO[1].isActive, true); + t.is(Object.hasOwn(foundUsersRO[1], 'email'), true); + t.is(Object.hasOwn(foundUsersRO[0], 'email'), true); + t.is(Object.hasOwn(foundUsersRO[0], 'createdAt'), true); + t.is(Object.hasOwn(foundUsersRO[1], 'createdAt'), true); + + t.pass(); }); test.serial(`${currentTest} should throw an exception, when connection id is incorrect`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createConnectionResponse.status, 201); - const connectionRO = JSON.parse(createConnectionResponse.text); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connectionRO.id}`) - .send(newGroup1) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - const createGroupRO = JSON.parse(createGroupResponse.text); - - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation(token, undefined, app, undefined); - - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: createGroupRO.id, - }; - - const addUserInGroupResponse = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - t.is(addUserInGroupResponse.status, 200); - - const fakeConnectionId = faker.string.uuid(); - const findAllUsersResponse = await request(app.getHttpServer()) - .get(`/connection/users/${fakeConnectionId}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const findAllUsersRO = JSON.parse(findAllUsersResponse.text); - t.is(findAllUsersResponse.status, 403); - t.is(findAllUsersRO.message, Messages.DONT_HAVE_PERMISSIONS); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createConnectionResponse.status, 201); + const connectionRO = JSON.parse(createConnectionResponse.text); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connectionRO.id}`) + .send(newGroup1) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + const createGroupRO = JSON.parse(createGroupResponse.text); + + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation(token, undefined, app, undefined); + + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: createGroupRO.id, + }; + + const addUserInGroupResponse = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + t.is(addUserInGroupResponse.status, 200); + + const fakeConnectionId = faker.string.uuid(); + const findAllUsersResponse = await request(app.getHttpServer()) + .get(`/connection/users/${fakeConnectionId}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const findAllUsersRO = JSON.parse(findAllUsersResponse.text); + t.is(findAllUsersResponse.status, 403); + t.is(findAllUsersRO.message, Messages.DONT_HAVE_PERMISSIONS); + + t.pass(); }); test(`${currentTest} should return a found connection`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - const findOneResponce = await request(app.getHttpServer()) - .get(`/connection/one/${createConnectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const foundOneRo = JSON.parse(findOneResponce.text); - console.log('🚀 ~ foundOneRo:', foundOneRo); - t.is(findOneResponce.status, 200); - const result = findOneResponce.body.connection; - - t.is(result.title, 'Test Connection'); - t.is(result.type, 'postgres'); - t.is(result.host, 'nestjs_testing'); - t.is(typeof result.port, 'number'); - t.is(result.port, 5432); - t.is(result.username, 'postgres'); - t.is(result.database, 'nestjs_testing'); - t.is(result.sid, null); - t.is(Object.hasOwn(result, 'createdAt'), true); - t.is(Object.hasOwn(result, 'updatedAt'), true); - t.is(Object.hasOwn(result, 'password'), false); - t.is(Object.hasOwn(result, 'groups'), false); - t.is(Object.hasOwn(result, 'author'), false); - t.is(Object.hasOwn(result, 'id'), true); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + const findOneResponce = await request(app.getHttpServer()) + .get(`/connection/one/${createConnectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const foundOneRo = JSON.parse(findOneResponce.text); + console.log('🚀 ~ foundOneRo:', foundOneRo); + t.is(findOneResponce.status, 200); + const result = findOneResponce.body.connection; + + t.is(result.title, 'Test Connection'); + t.is(result.type, 'postgres'); + t.is(result.host, 'nestjs_testing'); + t.is(typeof result.port, 'number'); + t.is(result.port, 5432); + t.is(result.username, 'postgres'); + t.is(result.database, 'nestjs_testing'); + t.is(result.sid, null); + t.is(Object.hasOwn(result, 'createdAt'), true); + t.is(Object.hasOwn(result, 'updatedAt'), true); + t.is(Object.hasOwn(result, 'password'), false); + t.is(Object.hasOwn(result, 'groups'), false); + t.is(Object.hasOwn(result, 'author'), false); + t.is(Object.hasOwn(result, 'id'), true); + + t.pass(); }); test.serial( - `${currentTest} should return a found connection when user not added into any connection group`, - async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createConnectionResponse.status, 201); - const connectionRO = JSON.parse(createConnectionResponse.text); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connectionRO.id}`) - .send(newGroup1) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - const _createGroupRO = JSON.parse(createGroupResponse.text); - - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation(token, undefined, app, undefined); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - const findOneResponse = await request(app.getHttpServer()) - .get(`/connection/one/${createConnectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', secondUserRegisterInfo.token) - .set('Accept', 'application/json'); - - const findOneConnectionRO = JSON.parse(findOneResponse.text); - t.is(findOneResponse.status, 200); - - t.is(Object.hasOwn(findOneConnectionRO.connection, 'id'), true); - t.is(Object.hasOwn(findOneConnectionRO.connection, 'title'), true); - t.is(Object.hasOwn(findOneConnectionRO.connection, 'type'), true); - t.is(Object.hasOwn(findOneConnectionRO.connection, 'host'), false); - t.is(Object.hasOwn(findOneConnectionRO.connection, 'port'), false); - t.is(Object.hasOwn(findOneConnectionRO.connection, 'username'), false); - t.is(Object.hasOwn(findOneConnectionRO.connection, 'database'), true); - t.is(Object.hasOwn(findOneConnectionRO.connection, 'sid'), false); - t.is(Object.hasOwn(findOneConnectionRO.connection, 'password'), false); - t.is(Object.hasOwn(findOneConnectionRO.connection, 'groups'), false); - t.is(Object.hasOwn(findOneConnectionRO.connection, 'author'), false); - t.is(findOneConnectionRO.accessLevel, AccessLevelEnum.none); - t.is(findOneConnectionRO.groupManagement, false); - t.is(findOneConnectionRO.connectionProperties, null); - t.pass(); - }, + `${currentTest} should return a found connection when user not added into any connection group`, + async (t) => { + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = + getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createConnectionResponse.status, 201); + const connectionRO = JSON.parse(createConnectionResponse.text); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connectionRO.id}`) + .send(newGroup1) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + const _createGroupRO = JSON.parse(createGroupResponse.text); + + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation(token, undefined, app, undefined); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + const findOneResponse = await request(app.getHttpServer()) + .get(`/connection/one/${createConnectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', secondUserRegisterInfo.token) + .set('Accept', 'application/json'); + + const findOneConnectionRO = JSON.parse(findOneResponse.text); + t.is(findOneResponse.status, 200); + + t.is(Object.hasOwn(findOneConnectionRO.connection, 'id'), true); + t.is(Object.hasOwn(findOneConnectionRO.connection, 'title'), true); + t.is(Object.hasOwn(findOneConnectionRO.connection, 'type'), true); + t.is(Object.hasOwn(findOneConnectionRO.connection, 'host'), false); + t.is(Object.hasOwn(findOneConnectionRO.connection, 'port'), false); + t.is(Object.hasOwn(findOneConnectionRO.connection, 'username'), false); + t.is(Object.hasOwn(findOneConnectionRO.connection, 'database'), true); + t.is(Object.hasOwn(findOneConnectionRO.connection, 'sid'), false); + t.is(Object.hasOwn(findOneConnectionRO.connection, 'password'), false); + t.is(Object.hasOwn(findOneConnectionRO.connection, 'groups'), false); + t.is(Object.hasOwn(findOneConnectionRO.connection, 'author'), false); + t.is(findOneConnectionRO.accessLevel, AccessLevelEnum.none); + t.is(findOneConnectionRO.groupManagement, false); + t.is(findOneConnectionRO.connectionProperties, null); + t.pass(); + }, ); test.serial( - `${currentTest} should throw an exception "id is missing" when connection id not passed in the request`, - async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - createConnectionRO.id = undefined; - const findOneResponce = await request(app.getHttpServer()) - .get(`/connection/one/${createConnectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(findOneResponce.status, 400); - const { message } = JSON.parse(findOneResponce.text); - t.is(message, Messages.UUID_INVALID); - - t.pass(); - }, + `${currentTest} should throw an exception "id is missing" when connection id not passed in the request`, + async (t) => { + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = + getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + createConnectionRO.id = undefined; + const findOneResponce = await request(app.getHttpServer()) + .get(`/connection/one/${createConnectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(findOneResponce.status, 400); + const { message } = JSON.parse(findOneResponce.text); + t.is(message, Messages.UUID_INVALID); + + t.pass(); + }, ); currentTest = 'POST /connection'; test.serial(`${currentTest} should return created connection`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(response.status, 201); - const result = JSON.parse(response.text); - - t.is(result.title, 'Test Connection'); - t.is(result.type, 'postgres'); - t.is(result.host, 'nestjs_testing'); - t.is(typeof result.port, 'number'); - t.is(result.port, 5432); - t.is(result.username, 'postgres'); - t.is(result.database, 'nestjs_testing'); - t.is(result.sid, null); - t.is(Object.hasOwn(result, 'createdAt'), true); - t.is(Object.hasOwn(result, 'updatedAt'), true); - t.is(Object.hasOwn(result, 'password'), false); - t.is(Object.hasOwn(result, 'groups'), true); - t.is(typeof result.groups, 'object'); - t.is(result.groups.length >= 1, true); - - const index = result.groups - .map((e) => { - return e.title; - }) - .indexOf('Admin'); - - t.is(index >= 0, true); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(response.status, 201); + const result = JSON.parse(response.text); + + t.is(result.title, 'Test Connection'); + t.is(result.type, 'postgres'); + t.is(result.host, 'nestjs_testing'); + t.is(typeof result.port, 'number'); + t.is(result.port, 5432); + t.is(result.username, 'postgres'); + t.is(result.database, 'nestjs_testing'); + t.is(result.sid, null); + t.is(Object.hasOwn(result, 'createdAt'), true); + t.is(Object.hasOwn(result, 'updatedAt'), true); + t.is(Object.hasOwn(result, 'password'), false); + t.is(Object.hasOwn(result, 'groups'), true); + t.is(typeof result.groups, 'object'); + t.is(result.groups.length >= 1, true); + + const index = result.groups + .map((e) => { + return e.title; + }) + .indexOf('Admin'); + + t.is(index >= 0, true); + + t.pass(); }); test.serial(`${currentTest} should throw error when create connection without type`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - delete newConnection.type; - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _responseObject = JSON.parse(response.text); - const { message } = JSON.parse(response.text); - t.is(response.status, 400); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + delete newConnection.type; + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _responseObject = JSON.parse(response.text); + const { message } = JSON.parse(response.text); + t.is(response.status, 400); + + t.pass(); }); test.serial(`${currentTest} should throw error when create connection without host`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - delete newConnection.host; - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - t.is(message, Messages.HOST_MISSING); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + delete newConnection.host; + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + t.is(message, Messages.HOST_MISSING); + + t.pass(); }); test.serial(`${currentTest} should throw error when create connection without port`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - delete newConnection.port; - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - t.is(message, `${Messages.PORT_MISSING}, ${Messages.PORT_FORMAT_INCORRECT}`); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + delete newConnection.port; + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + t.is(message, `${Messages.PORT_MISSING}, ${Messages.PORT_FORMAT_INCORRECT}`); + + t.pass(); }); test.serial(`${currentTest} should throw error when create connection wit port value more than 65535`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - newConnection.port = 65536; - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + newConnection.port = 65536; + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + + t.pass(); }); test.serial(`${currentTest} should throw error when create connection wit port value less than 0`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - newConnection.port = -1; - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + newConnection.port = -1; + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + t.pass(); }); test.serial(`${currentTest} should throw error when create connection without username`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - delete newConnection.username; - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - t.is(message, Messages.USERNAME_MISSING); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + delete newConnection.username; + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + t.is(message, Messages.USERNAME_MISSING); + + t.pass(); }); test.serial(`${currentTest} should throw error when create connection without database`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - delete newConnection.database; - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - t.is(message, Messages.DATABASE_MISSING); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + delete newConnection.database; + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + t.is(message, Messages.DATABASE_MISSING); + + t.pass(); }); test.serial(`${currentTest} should throw error when create connection without password`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - delete newConnection.password; - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - t.is(message, Messages.PASSWORD_MISSING); - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + delete newConnection.password; + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + t.is(message, Messages.PASSWORD_MISSING); + t.pass(); }); test.serial( - `${currentTest} should throw error with complex message when create connection without database, type, port`, - async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - delete newConnection.database; - delete newConnection.type; - delete newConnection.port; - - const response = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - - t.pass(); - }, + `${currentTest} should throw error with complex message when create connection without database, type, port`, + async (t) => { + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = + getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + delete newConnection.database; + delete newConnection.type; + delete newConnection.port; + + const response = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + + t.pass(); + }, ); currentTest = 'PUT /connection'; test.serial(`${currentTest} should return updated connection`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - const updateConnectionResponse = await request(app.getHttpServer()) - .put(`/connection/${createConnectionRO.id}`) - .send(updateConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(updateConnectionResponse.status, 200); - const result = updateConnectionResponse.body.connection; - - t.is(result.title, 'Updated Test Connection'); - t.is(result.type, 'postgres'); - t.is(result.host, 'testing_nestjs'); - t.is(typeof result.port, 'number'); - t.is(result.port, 5432); - t.is(result.username, 'admin'); - t.is(result.database, 'testing_nestjs'); - t.is(result.sid, null); - t.is(Object.hasOwn(result, 'createdAt'), true); - t.is(Object.hasOwn(result, 'updatedAt'), true); - t.is(Object.hasOwn(result, 'password'), false); - t.is(Object.hasOwn(result, 'groups'), false); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + const updateConnectionResponse = await request(app.getHttpServer()) + .put(`/connection/${createConnectionRO.id}`) + .send(updateConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(updateConnectionResponse.status, 200); + const result = updateConnectionResponse.body.connection; + + t.is(result.title, 'Updated Test Connection'); + t.is(result.type, 'postgres'); + t.is(result.host, 'testing_nestjs'); + t.is(typeof result.port, 'number'); + t.is(result.port, 5432); + t.is(result.username, 'admin'); + t.is(result.database, 'testing_nestjs'); + t.is(result.sid, null); + t.is(Object.hasOwn(result, 'createdAt'), true); + t.is(Object.hasOwn(result, 'updatedAt'), true); + t.is(Object.hasOwn(result, 'password'), false); + t.is(Object.hasOwn(result, 'groups'), false); + + t.pass(); }); test.serial(`${currentTest} 'should throw error when update connection without type'`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - delete updateConnection.type; - - const response = await request(app.getHttpServer()) - .put(`/connection/${createConnectionRO.id}`) - .send(updateConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + delete updateConnection.type; + + const response = await request(app.getHttpServer()) + .put(`/connection/${createConnectionRO.id}`) + .send(updateConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + + t.pass(); }); test.serial(`${currentTest} should throw error when update connection without host`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - delete updateConnection.host; - - const response = await request(app.getHttpServer()) - .put(`/connection/${createConnectionRO.id}`) - .send(updateConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - t.is(message, Messages.HOST_MISSING); - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + delete updateConnection.host; + + const response = await request(app.getHttpServer()) + .put(`/connection/${createConnectionRO.id}`) + .send(updateConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + t.is(message, Messages.HOST_MISSING); + t.pass(); }); test.serial(`${currentTest} should throw error when update connection without port`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - delete updateConnection.port; - - const response = await request(app.getHttpServer()) - .put(`/connection/${createConnectionRO.id}`) - .send(updateConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - t.is(message, `${Messages.PORT_MISSING}, ${Messages.PORT_FORMAT_INCORRECT}`); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + delete updateConnection.port; + + const response = await request(app.getHttpServer()) + .put(`/connection/${createConnectionRO.id}`) + .send(updateConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + t.is(message, `${Messages.PORT_MISSING}, ${Messages.PORT_FORMAT_INCORRECT}`); + + t.pass(); }); test.serial(`${currentTest} should throw error when update connection wit port value more than 65535`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - updateConnection.port = 65536; - - const response = await request(app.getHttpServer()) - .put(`/connection/${createConnectionRO.id}`) - .send(updateConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + updateConnection.port = 65536; + + const response = await request(app.getHttpServer()) + .put(`/connection/${createConnectionRO.id}`) + .send(updateConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + + t.pass(); }); test.serial(`${currentTest} should throw error when update connection wit port value less than 0`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - updateConnection.port = -1; - - const response = await request(app.getHttpServer()) - .put(`/connection/${createConnectionRO.id}`) - .send(updateConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + updateConnection.port = -1; + + const response = await request(app.getHttpServer()) + .put(`/connection/${createConnectionRO.id}`) + .send(updateConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + + t.pass(); }); test.serial(`${currentTest} should throw error when update connection without username`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - delete updateConnection.username; - - const response = await request(app.getHttpServer()) - .put(`/connection/${createConnectionRO.id}`) - .send(updateConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - t.is(message, Messages.USERNAME_MISSING); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + delete updateConnection.username; + + const response = await request(app.getHttpServer()) + .put(`/connection/${createConnectionRO.id}`) + .send(updateConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + t.is(message, Messages.USERNAME_MISSING); + + t.pass(); }); test.serial(`${currentTest} should throw error when update connection without database`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - delete updateConnection.database; - - const response = await request(app.getHttpServer()) - .put(`/connection/${createConnectionRO.id}`) - .send(updateConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - t.is(message, Messages.DATABASE_MISSING); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + delete updateConnection.database; + + const response = await request(app.getHttpServer()) + .put(`/connection/${createConnectionRO.id}`) + .send(updateConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + t.is(message, Messages.DATABASE_MISSING); + + t.pass(); }); test.serial( - `${currentTest} should throw error with complex message when update connection without database, type, port`, - async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - delete updateConnection.database; - delete updateConnection.type; - delete updateConnection.port; - - const response = await request(app.getHttpServer()) - .put(`/connection/${createConnectionRO.id}`) - .send(updateConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 400); - const { message } = JSON.parse(response.text); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - - t.pass(); - }, + `${currentTest} should throw error with complex message when update connection without database, type, port`, + async (t) => { + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = + getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + delete updateConnection.database; + delete updateConnection.type; + delete updateConnection.port; + + const response = await request(app.getHttpServer()) + .put(`/connection/${createConnectionRO.id}`) + .send(updateConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 400); + const { message } = JSON.parse(response.text); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + + t.pass(); + }, ); currentTest = 'DELETE /connection/:slug'; test.serial(`${currentTest} should return delete result`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - - const response = await request(app.getHttpServer()) - .put(`/connection/delete/${createConnectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 200); - const result = response.body; - - //deleted connection not found in database - const findOneResponce = await request(app.getHttpServer()) - .get(`/connection/one/${createConnectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(findOneResponce.status, 400); - - const { message } = JSON.parse(findOneResponce.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - - t.is(Object.hasOwn(result, 'id'), false); - t.is(result.title, 'Test Connection'); - t.is(result.type, 'postgres'); - t.is(result.host, 'nestjs_testing'); - t.is(typeof result.port, 'number'); - t.is(result.port, 5432); - t.is(result.username, 'postgres'); - t.is(result.database, 'nestjs_testing'); - t.is(result.sid, null); - t.is(Object.hasOwn(result, 'createdAt'), true); - t.is(Object.hasOwn(result, 'updatedAt'), true); - t.is(Object.hasOwn(result, 'password'), false); - t.is(Object.hasOwn(result, 'groups'), false); - t.is(Object.hasOwn(result, 'author'), false); - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + + const response = await request(app.getHttpServer()) + .put(`/connection/delete/${createConnectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 200); + const result = response.body; + + //deleted connection not found in database + const findOneResponce = await request(app.getHttpServer()) + .get(`/connection/one/${createConnectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(findOneResponce.status, 400); + + const { message } = JSON.parse(findOneResponce.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + + t.is(Object.hasOwn(result, 'id'), false); + t.is(result.title, 'Test Connection'); + t.is(result.type, 'postgres'); + t.is(result.host, 'nestjs_testing'); + t.is(typeof result.port, 'number'); + t.is(result.port, 5432); + t.is(result.username, 'postgres'); + t.is(result.database, 'nestjs_testing'); + t.is(result.sid, null); + t.is(Object.hasOwn(result, 'createdAt'), true); + t.is(Object.hasOwn(result, 'updatedAt'), true); + t.is(Object.hasOwn(result, 'password'), false); + t.is(Object.hasOwn(result, 'groups'), false); + t.is(Object.hasOwn(result, 'author'), false); + t.pass(); }); test.serial(`${currentTest} should throw an exception when connection not found`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - createConnectionRO.id = faker.string.uuid(); - - const response = await request(app.getHttpServer()) - .put(`/connection/delete/${createConnectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 403); - - const { message } = JSON.parse(response.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + createConnectionRO.id = faker.string.uuid(); + + const response = await request(app.getHttpServer()) + .put(`/connection/delete/${createConnectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 403); + + const { message } = JSON.parse(response.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + t.pass(); }); test.serial(`${currentTest} should throw an exception when connection id not passed in the request`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResult.text); - createConnectionRO.id = ''; + const createConnectionRO = JSON.parse(createConnectionResult.text); + createConnectionRO.id = ''; - const response = await request(app.getHttpServer()) - .delete(`/connection/${createConnectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); + const response = await request(app.getHttpServer()) + .delete(`/connection/${createConnectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); - t.is(response.status, 404); + t.is(response.status, 404); - t.pass(); + t.pass(); }); currentTest = 'POST /connection/group/:slug'; test.serial(`${currentTest} should return a created group`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token, email } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(createGroupResponse.status, 201); - const result = JSON.parse(createGroupResponse.text); - - t.is(result.title, newGroup1.title); - t.is(Object.hasOwn(result, 'users'), true); - t.is(typeof result.users, 'object'); - t.is(result.users.length, 1); - t.is(result.users[0].email, email.toLowerCase()); - t.is(result.users[0].isActive, false); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token, email } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(createGroupResponse.status, 201); + const result = JSON.parse(createGroupResponse.text); + + t.is(result.title, newGroup1.title); + t.is(Object.hasOwn(result, 'users'), true); + t.is(typeof result.users, 'object'); + t.is(result.users.length, 1); + t.is(result.users[0].email, email.toLowerCase()); + t.is(result.users[0].isActive, false); + + t.pass(); }); test.serial(`${currentTest} throw an exception when connectionId not passed in request`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - createConnectionRO.id = ''; - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(createGroupResponse.status, 404); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + createConnectionRO.id = ''; + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(createGroupResponse.status, 404); + + t.pass(); }); test.serial(`${currentTest} throw an exception when group title not passed in request`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - delete newGroup1.title; - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const { message } = JSON.parse(createGroupResponse.text); - - t.is(createGroupResponse.status, 400); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + delete newGroup1.title; + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const { message } = JSON.parse(createGroupResponse.text); + + t.is(createGroupResponse.status, 400); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + + t.pass(); }); test.serial(`${currentTest} throw an exception when connectionId is incorrect`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - createConnectionRO.id = faker.string.uuid(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const { message } = JSON.parse(createGroupResponse.text); - - t.is(createGroupResponse.status, 403); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + createConnectionRO.id = faker.string.uuid(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const { message } = JSON.parse(createGroupResponse.text); + + t.is(createGroupResponse.status, 403); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + t.pass(); }); test(`${currentTest} throw an exception when group name is not unique`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .set('Cookie', token) - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - newGroup1.title = 'Admin'; - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(createGroupResponse.text); - - t.is(createGroupResponse.status, 400); - t.is(message, Messages.GROUP_NAME_UNIQUE); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .set('Cookie', token) + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + newGroup1.title = 'Admin'; + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(createGroupResponse.text); + + t.is(createGroupResponse.status, 400); + t.is(message, Messages.GROUP_NAME_UNIQUE); + + t.pass(); }); currentTest = 'PUT /connection/group/delete/:slug'; test.serial(`${currentTest} should return connection without deleted group result`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - // create group in connection - let result = createGroupResponse.body; - - t.is(createGroupResponse.status, 201); - - t.is(Object.hasOwn(result, 'id'), true); - t.is(result.title, newGroup1.title); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - let response = await request(app.getHttpServer()) - .put(`/connection/group/delete/${createConnectionRO.id}`) - .send({ groupId: createGroupRO.id }) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - //after deleting group - result = response.body; - - t.is(response.status, 200); - t.is(Object.hasOwn(result, 'title'), true); - t.is(result.title, createGroupRO.title); - t.is(result.isMain, false); - // check that group was deleted - - response = await request(app.getHttpServer()) - .get(`/connection/groups/${createConnectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 200); - result = JSON.parse(response.text); - t.is(result.length, 1); - const _groupId = result[0].group.id; - - t.is(Object.hasOwn(result[0].group, 'title'), true); - t.is(result[0].accessLevel, AccessLevelEnum.edit); - - const index = result - .map((e) => { - return e.group.title; - }) - .indexOf('Admin'); - - t.is(index >= 0, true); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + // create group in connection + let result = createGroupResponse.body; + + t.is(createGroupResponse.status, 201); + + t.is(Object.hasOwn(result, 'id'), true); + t.is(result.title, newGroup1.title); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + let response = await request(app.getHttpServer()) + .put(`/connection/group/delete/${createConnectionRO.id}`) + .send({ groupId: createGroupRO.id }) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + //after deleting group + result = response.body; + + t.is(response.status, 200); + t.is(Object.hasOwn(result, 'title'), true); + t.is(result.title, createGroupRO.title); + t.is(result.isMain, false); + // check that group was deleted + + response = await request(app.getHttpServer()) + .get(`/connection/groups/${createConnectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 200); + result = JSON.parse(response.text); + t.is(result.length, 1); + const _groupId = result[0].group.id; + + t.is(Object.hasOwn(result[0].group, 'title'), true); + t.is(result[0].accessLevel, AccessLevelEnum.edit); + + const index = result + .map((e) => { + return e.group.title; + }) + .indexOf('Admin'); + + t.is(index >= 0, true); + + t.pass(); }); test.serial(`${currentTest}`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + t.pass(); }); test.serial(`${currentTest} should throw an exception when connection id is not passed in the request`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - // create group in connection - const result = createGroupResponse.body; - - t.is(createGroupResponse.status, 201); - - t.is(Object.hasOwn(result, 'id'), true); - t.is(result.title, newGroup1.title); - - const createGroupRO = JSON.parse(createGroupResponse.text); - createConnectionRO.id = ''; - const response = await request(app.getHttpServer()) - .put(`/connection/group/delete/${createConnectionRO.id}`) - .send({ groupId: createGroupRO.id }) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(response.status, 404); - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + // create group in connection + const result = createGroupResponse.body; + + t.is(createGroupResponse.status, 201); + + t.is(Object.hasOwn(result, 'id'), true); + t.is(result.title, newGroup1.title); + + const createGroupRO = JSON.parse(createGroupResponse.text); + createConnectionRO.id = ''; + const response = await request(app.getHttpServer()) + .put(`/connection/group/delete/${createConnectionRO.id}`) + .send({ groupId: createGroupRO.id }) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(response.status, 404); + t.pass(); }); test.serial(`${currentTest} should throw an exception when group id is not passed in the request`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - // create group in connection - const result = createGroupResponse.body; - - t.is(createGroupResponse.status, 201); - - t.is(Object.hasOwn(result, 'id'), true); - t.is(result.title, newGroup1.title); - - const createGroupRO = JSON.parse(createGroupResponse.text); - delete createGroupRO.id; - const response = await request(app.getHttpServer()) - .put(`/connection/group/delete/${createConnectionRO.id}`) - .send({ groupId: createGroupRO.id }) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(response.text); - t.is(response.status, 400); - t.is(message, Messages.PARAMETER_NAME_MISSING('groupId')); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + // create group in connection + const result = createGroupResponse.body; + + t.is(createGroupResponse.status, 201); + + t.is(Object.hasOwn(result, 'id'), true); + t.is(result.title, newGroup1.title); + + const createGroupRO = JSON.parse(createGroupResponse.text); + delete createGroupRO.id; + const response = await request(app.getHttpServer()) + .put(`/connection/group/delete/${createConnectionRO.id}`) + .send({ groupId: createGroupRO.id }) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(response.text); + t.is(response.status, 400); + t.is(message, Messages.PARAMETER_NAME_MISSING('groupId')); + + t.pass(); }); test.serial(`${currentTest} should throw an exception when group id is incorrect`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - // create group in connection - const result = createGroupResponse.body; - - t.is(createGroupResponse.status, 201); - - t.is(Object.hasOwn(result, 'id'), true); - t.is(result.title, newGroup1.title); - - const createGroupRO = JSON.parse(createGroupResponse.text); - createGroupRO.id = faker.string.uuid(); - const response = await request(app.getHttpServer()) - .put(`/connection/group/delete/${createConnectionRO.id}`) - .send({ groupId: createGroupRO.id }) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(response.text); - t.is(response.status, 400); - t.is(message, Messages.GROUP_NOT_FOUND); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + // create group in connection + const result = createGroupResponse.body; + + t.is(createGroupResponse.status, 201); + + t.is(Object.hasOwn(result, 'id'), true); + t.is(result.title, newGroup1.title); + + const createGroupRO = JSON.parse(createGroupResponse.text); + createGroupRO.id = faker.string.uuid(); + const response = await request(app.getHttpServer()) + .put(`/connection/group/delete/${createConnectionRO.id}`) + .send({ groupId: createGroupRO.id }) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(response.text); + t.is(response.status, 400); + t.is(message, Messages.GROUP_NOT_FOUND); + + t.pass(); }); test.serial(`${currentTest} should throw an exception when connection id is incorrect`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - // create group in connection - const result = createGroupResponse.body; - - t.is(createGroupResponse.status, 201); - - t.is(Object.hasOwn(result, 'id'), true); - t.is(result.title, newGroup1.title); - - const createGroupRO = JSON.parse(createGroupResponse.text); - createConnectionRO.id = faker.string.uuid(); - const response = await request(app.getHttpServer()) - .put(`/connection/group/delete/${createConnectionRO.id}`) - .send({ groupId: createGroupRO.id }) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const { message } = JSON.parse(response.text); - t.is(response.status, 403); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + // create group in connection + const result = createGroupResponse.body; + + t.is(createGroupResponse.status, 201); + + t.is(Object.hasOwn(result, 'id'), true); + t.is(result.title, newGroup1.title); + + const createGroupRO = JSON.parse(createGroupResponse.text); + createConnectionRO.id = faker.string.uuid(); + const response = await request(app.getHttpServer()) + .put(`/connection/group/delete/${createConnectionRO.id}`) + .send({ groupId: createGroupRO.id }) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const { message } = JSON.parse(response.text); + t.is(response.status, 403); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + t.pass(); }); test.serial(`${currentTest} should throw an exception when trying delete admin group`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - - const response = await request(app.getHttpServer()) - .put(`/connection/group/delete/${createConnectionRO.id}`) - .send({ groupId: createConnectionRO.groups[0].id }) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const { message } = JSON.parse(response.text); - t.is(response.status, 403); - t.is(message, Messages.CANT_DELETE_ADMIN_GROUP); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + + const response = await request(app.getHttpServer()) + .put(`/connection/group/delete/${createConnectionRO.id}`) + .send({ groupId: createConnectionRO.groups[0].id }) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const { message } = JSON.parse(response.text); + t.is(response.status, 403); + t.is(message, Messages.CANT_DELETE_ADMIN_GROUP); + + t.pass(); }); currentTest = 'PUT /connection/encryption/restore/:slug'; test.serial(`${currentTest} should return restored connection`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const newPgConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); - newPgConnection.masterEncryption = true; - - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newPgConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResult.status, 201); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - const { id, groups } = createConnectionRO; - const groupId = groups[0].id; - const restoreConnectionResult = await request(app.getHttpServer()) - .put(`/connection/encryption/restore/${id}`) - .send(newPgConnection) - .set('masterpwd', 'hamalaiahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(restoreConnectionResult.status, 200); - const restoreConnectionResultRO = JSON.parse(restoreConnectionResult.text); - const { connection } = restoreConnectionResultRO; - t.is(connection.id, id); - - const response = await request(app.getHttpServer()) - .get(`/connection/groups/${id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const result = JSON.parse(response.text); - t.is(response.status, 200); - const groupIdInRestoredConnection = result[0].group.id; - t.is(groupIdInRestoredConnection, groupId); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const newPgConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); + newPgConnection.masterEncryption = true; + + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newPgConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResult.status, 201); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + const { id, groups } = createConnectionRO; + const groupId = groups[0].id; + const restoreConnectionResult = await request(app.getHttpServer()) + .put(`/connection/encryption/restore/${id}`) + .send(newPgConnection) + .set('masterpwd', 'hamalaiahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(restoreConnectionResult.status, 200); + const restoreConnectionResultRO = JSON.parse(restoreConnectionResult.text); + const { connection } = restoreConnectionResultRO; + t.is(connection.id, id); + + const response = await request(app.getHttpServer()) + .get(`/connection/groups/${id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const result = JSON.parse(response.text); + t.is(response.status, 200); + const groupIdInRestoredConnection = result[0].group.id; + t.is(groupIdInRestoredConnection, groupId); + + t.pass(); }); test.serial( - `${currentTest} should return restored connection. Restored connection should will return list of tables correctly`, - async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const newPgConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); - newPgConnection.masterEncryption = true; - - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newPgConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResult.status, 201); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - const { id, groups } = createConnectionRO; - const _groupId = groups[0].id; - const restoreConnectionResult = await request(app.getHttpServer()) - .put(`/connection/encryption/restore/${id}`) - .send(newPgConnection) - .set('masterpwd', 'hamalaiahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(restoreConnectionResult.status, 200); - const restoreConnectionResultRO = JSON.parse(restoreConnectionResult.text); - const { connection } = restoreConnectionResultRO; - t.is(connection.id, id); - - const findTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${id}`) - .set('Content-Type', 'application/json') - .set('masterpwd', 'hamalaiahalai') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const tables = JSON.parse(findTablesResponse.text); - - t.is(findTablesResponse.status, 200); - t.is(tables.length > 0, true); - }, + `${currentTest} should return restored connection. Restored connection should will return list of tables correctly`, + async (t) => { + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = + getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const newPgConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); + newPgConnection.masterEncryption = true; + + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newPgConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResult.status, 201); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + const { id, groups } = createConnectionRO; + const _groupId = groups[0].id; + const restoreConnectionResult = await request(app.getHttpServer()) + .put(`/connection/encryption/restore/${id}`) + .send(newPgConnection) + .set('masterpwd', 'hamalaiahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(restoreConnectionResult.status, 200); + const restoreConnectionResultRO = JSON.parse(restoreConnectionResult.text); + const { connection } = restoreConnectionResultRO; + t.is(connection.id, id); + + const findTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${id}`) + .set('Content-Type', 'application/json') + .set('masterpwd', 'hamalaiahalai') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const tables = JSON.parse(findTablesResponse.text); + + t.is(findTablesResponse.status, 200); + t.is(tables.length > 0, true); + }, ); currentTest = 'GET /connection/groups/:slug'; test.serial(`${currentTest} should groups in connection`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(createGroupResponse.status, 201); - - const response = await request(app.getHttpServer()) - .get(`/connection/groups/${createConnectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 200); - const result = JSON.parse(response.text); - const _groupId = result[0].group.id; - - t.is(Object.hasOwn(result[1].group, 'title'), true); - t.is(result[0].accessLevel, AccessLevelEnum.edit); - - const index = result - .map((e) => { - return e.group.title; - }) - .indexOf('Admin'); - - t.is(index >= 0, true); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(createGroupResponse.status, 201); + + const response = await request(app.getHttpServer()) + .get(`/connection/groups/${createConnectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 200); + const result = JSON.parse(response.text); + const _groupId = result[0].group.id; + + t.is(Object.hasOwn(result[1].group, 'title'), true); + t.is(result[0].accessLevel, AccessLevelEnum.edit); + + const index = result + .map((e) => { + return e.group.title; + }) + .indexOf('Admin'); + + t.is(index >= 0, true); + + t.pass(); }); test.serial(`${currentTest} should throw an exception when connection id not passed in the request`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(createGroupResponse.status, 201); - - createConnectionRO.id = ''; - const response = await request(app.getHttpServer()) - .get(`/connection/groups/${createConnectionRO.id}`) - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(response.status, 404); - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(createGroupResponse.status, 201); + + createConnectionRO.id = ''; + const response = await request(app.getHttpServer()) + .get(`/connection/groups/${createConnectionRO.id}`) + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(response.status, 404); + t.pass(); }); test.serial(`${currentTest} should throw an exception when connection id is invalid`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(createGroupResponse.status, 201); - createConnectionRO.id = faker.string.uuid(); - const response = await request(app.getHttpServer()) - .get(`/connection/groups/${createConnectionRO.id}`) - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(response.status, 200); - const getGroupsRO = JSON.parse(response.text); - t.is(Array.isArray(getGroupsRO), true); - t.is(getGroupsRO.length, 0); - - t.pass(); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(createGroupResponse.status, 201); + createConnectionRO.id = faker.string.uuid(); + const response = await request(app.getHttpServer()) + .get(`/connection/groups/${createConnectionRO.id}`) + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(response.status, 200); + const getGroupsRO = JSON.parse(response.text); + t.is(Array.isArray(getGroupsRO), true); + t.is(getGroupsRO.length, 0); + + t.pass(); }); currentTest = 'POST /connection/test/'; test.serial(`${currentTest} should test connection and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const testConnectionResponse = await request(app.getHttpServer()) - .post('/connection/test/') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse.status, 201); - const { message } = JSON.parse(testConnectionResponse.text); - t.is(message, 'Successfully connected'); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const testConnectionResponse = await request(app.getHttpServer()) + .post('/connection/test/') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse.status, 201); + const { message } = JSON.parse(testConnectionResponse.text); + t.is(message, 'Successfully connected'); }); test.serial( - `${currentTest} should be successfully tested after update and without changing password during update`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - // test connection - const testConnectionResponse = await request(app.getHttpServer()) - .post('/connection/test/') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse.status, 201); - const { message } = JSON.parse(testConnectionResponse.text); - t.is(message, 'Successfully connected'); - - // create connection - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createConnectionResponse.status, 201); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - // test newly created connection - - const testConnectionResponse2 = await request(app.getHttpServer()) - .post('/connection/test/?connectionId=' + createConnectionRO.id) - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse2.status, 201); - const { message: message2 } = JSON.parse(testConnectionResponse2.text); - t.is(message2, 'Successfully connected'); - - // test connection with some changed properties and removed password property - - const connectionToTestDB2 = { ...connectionToTestDB }; - connectionToTestDB2.title = 'Test Connection 2'; - delete connectionToTestDB2.password; - - const testConnectionResponse3 = await request(app.getHttpServer()) - .post('/connection/test/?connectionId=' + createConnectionRO.id) - .send(connectionToTestDB2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse3.status, 201); - const { message: message3 } = JSON.parse(testConnectionResponse3.text); - t.is(message3, 'Successfully connected'); - - // encrypt connection with master password - - const connectionToTestDB3 = { ...connectionToTestDB2 }; - delete connectionToTestDB3.password; - connectionToTestDB3.masterEncryption = true; - const encryptConnectionResponse = await request(app.getHttpServer()) - .put(`/connection/${createConnectionRO.id}`) - .send(connectionToTestDB3) - .set('Cookie', firstUserToken) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(encryptConnectionResponse.status, 200); - const _encryptConnectionRO = JSON.parse(encryptConnectionResponse.text); - - // test encrypted connection - const testConnectionResponse4 = await request(app.getHttpServer()) - .post('/connection/test/?connectionId=' + createConnectionRO.id) - .send(connectionToTestDB2) - .set('Cookie', firstUserToken) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse4.status, 201); - const { message: message4 } = JSON.parse(testConnectionResponse4.text); - t.is(message4, 'Successfully connected'); - }, + `${currentTest} should be successfully tested after update and without changing password during update`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + // test connection + const testConnectionResponse = await request(app.getHttpServer()) + .post('/connection/test/') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse.status, 201); + const { message } = JSON.parse(testConnectionResponse.text); + t.is(message, 'Successfully connected'); + + // create connection + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createConnectionResponse.status, 201); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + // test newly created connection + + const testConnectionResponse2 = await request(app.getHttpServer()) + .post('/connection/test/?connectionId=' + createConnectionRO.id) + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse2.status, 201); + const { message: message2 } = JSON.parse(testConnectionResponse2.text); + t.is(message2, 'Successfully connected'); + + // test connection with some changed properties and removed password property + + const connectionToTestDB2 = { ...connectionToTestDB }; + connectionToTestDB2.title = 'Test Connection 2'; + delete connectionToTestDB2.password; + + const testConnectionResponse3 = await request(app.getHttpServer()) + .post('/connection/test/?connectionId=' + createConnectionRO.id) + .send(connectionToTestDB2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse3.status, 201); + const { message: message3 } = JSON.parse(testConnectionResponse3.text); + t.is(message3, 'Successfully connected'); + + // encrypt connection with master password + + const connectionToTestDB3 = { ...connectionToTestDB2 }; + delete connectionToTestDB3.password; + connectionToTestDB3.masterEncryption = true; + const encryptConnectionResponse = await request(app.getHttpServer()) + .put(`/connection/${createConnectionRO.id}`) + .send(connectionToTestDB3) + .set('Cookie', firstUserToken) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(encryptConnectionResponse.status, 200); + const _encryptConnectionRO = JSON.parse(encryptConnectionResponse.text); + + // test encrypted connection + const testConnectionResponse4 = await request(app.getHttpServer()) + .post('/connection/test/?connectionId=' + createConnectionRO.id) + .send(connectionToTestDB2) + .set('Cookie', firstUserToken) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse4.status, 201); + const { message: message4 } = JSON.parse(testConnectionResponse4.text); + t.is(message4, 'Successfully connected'); + }, ); currentTest = 'GET /connection/masterpwd/verify/:connectionId'; test.serial(`${currentTest} should return positive result if passed connection master password is valid`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const newPgConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); - newPgConnection.masterEncryption = true; - - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newPgConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResult.status, 201); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - const { id } = createConnectionRO; - - const masterPwdValidationResponse = await request(app.getHttpServer()) - .get(`/connection/masterpwd/verify/${id}`) - .set('masterpwd', 'ahalaimahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(masterPwdValidationResponse.status, 200); - const { isValid } = JSON.parse(masterPwdValidationResponse.text); - t.is(isValid, true); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const newPgConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); + newPgConnection.masterEncryption = true; + + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newPgConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResult.status, 201); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + const { id } = createConnectionRO; + + const masterPwdValidationResponse = await request(app.getHttpServer()) + .get(`/connection/masterpwd/verify/${id}`) + .set('masterpwd', 'ahalaimahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(masterPwdValidationResponse.status, 200); + const { isValid } = JSON.parse(masterPwdValidationResponse.text); + t.is(isValid, true); }); test.serial(`${currentTest} negative result if passed connection master password is invalid`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const newPgConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); - newPgConnection.masterEncryption = true; - - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newPgConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResult.status, 201); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - const { id } = createConnectionRO; - - const masterPwdValidationResponse = await request(app.getHttpServer()) - .get(`/connection/masterpwd/verify/${id}`) - .set('masterpwd', 'invalidMaterPwd') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(masterPwdValidationResponse.status, 200); - const { isValid } = JSON.parse(masterPwdValidationResponse.text); - t.is(isValid, false); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const newPgConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); + newPgConnection.masterEncryption = true; + + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newPgConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResult.status, 201); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + const { id } = createConnectionRO; + + const masterPwdValidationResponse = await request(app.getHttpServer()) + .get(`/connection/masterpwd/verify/${id}`) + .set('masterpwd', 'invalidMaterPwd') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(masterPwdValidationResponse.status, 200); + const { isValid } = JSON.parse(masterPwdValidationResponse.text); + t.is(isValid, false); }); currentTest = `PUT /connection/unfreeze/:connectionId`; test.serial(`${currentTest} should unfreeze connection`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = - getTestConnectionData(); - const { token } = await registerUserAndReturnUserInfo(app); - const newPgConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); - - const createConnectionResult = await request(app.getHttpServer()) - .post('/connection') - .send(newPgConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResult.status, 201); - - const createConnectionRO = JSON.parse(createConnectionResult.text); - const { id } = createConnectionRO; - - const unfreezeConnectionResponse = await request(app.getHttpServer()) - .put(`/connection/unfreeze/${id}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(unfreezeConnectionResponse.status, 200); - const unfreezeConnectionRO = JSON.parse(unfreezeConnectionResponse.text); - t.is(unfreezeConnectionRO.success, true); - - const findOneResponce = await request(app.getHttpServer()) - .get(`/connection/one/${id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - t.is(findOneResponce.status, 200); - const result = findOneResponce.body.connection; - t.is(result.isFrozen, false); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestConnectionData(); + const { token } = await registerUserAndReturnUserInfo(app); + const newPgConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); + + const createConnectionResult = await request(app.getHttpServer()) + .post('/connection') + .send(newPgConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResult.status, 201); + + const createConnectionRO = JSON.parse(createConnectionResult.text); + const { id } = createConnectionRO; + + const unfreezeConnectionResponse = await request(app.getHttpServer()) + .put(`/connection/unfreeze/${id}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(unfreezeConnectionResponse.status, 200); + const unfreezeConnectionRO = JSON.parse(unfreezeConnectionResponse.text); + t.is(unfreezeConnectionRO.success, true); + + const findOneResponce = await request(app.getHttpServer()) + .get(`/connection/one/${id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + t.is(findOneResponce.status, 200); + const result = findOneResponce.body.connection; + t.is(result.isFrozen, false); }); diff --git a/backend/test/ava-tests/saas-tests/connection-properties-e2e.test.ts b/backend/test/ava-tests/saas-tests/connection-properties-e2e.test.ts index 6b71559b8..2c278e52a 100644 --- a/backend/test/ava-tests/saas-tests/connection-properties-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/connection-properties-e2e.test.ts @@ -31,639 +31,636 @@ const testTables: Array = []; let currentTest; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - _testUtils = moduleFixture.get(TestUtils); - - app = moduleFixture.createNestApplication(); - app.use(cookieParser()); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + _testUtils = moduleFixture.get(TestUtils); + + app = moduleFixture.createNestApplication(); + app.use(cookieParser()); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); async function resetPostgresTestDB(testTableName) { - const Knex = getTestKnex(mockFactory.generateConnectionToTestPostgresDBInDocker()); - await Knex.schema.createTableIfNotExists(testTableName, (table) => { - table.increments(); - table.string(testTableColumnName); - table.string(testTAbleSecondColumnName); - table.timestamps(); - }); - - for (let i = 0; i < testEntitiesSeedsCount; i++) { - if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { - await Knex(testTableName).insert({ - [testTableColumnName]: testSearchedUserName, - [testTAbleSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - }); - } else { - await Knex(testTableName).insert({ - [testTableColumnName]: faker.person.firstName(), - [testTAbleSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - }); - } - } + const Knex = getTestKnex(mockFactory.generateConnectionToTestPostgresDBInDocker()); + await Knex.schema.createTableIfNotExists(testTableName, (table) => { + table.increments(); + table.string(testTableColumnName); + table.string(testTAbleSecondColumnName); + table.timestamps(); + }); + + for (let i = 0; i < testEntitiesSeedsCount; i++) { + if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { + await Knex(testTableName).insert({ + [testTableColumnName]: testSearchedUserName, + [testTAbleSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + }); + } else { + await Knex(testTableName).insert({ + [testTableColumnName]: faker.person.firstName(), + [testTAbleSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + }); + } + } } test.beforeEach(async (_t) => { - testTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - testTables.push(testTableName); - newConnectionProperties = mockFactory.generateConnectionPropertiesUserExcluded(testTableName); - await resetPostgresTestDB(testTableName); + testTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + testTables.push(testTableName); + newConnectionProperties = mockFactory.generateConnectionPropertiesUserExcluded(testTableName); + await resetPostgresTestDB(testTableName); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After custom field error: ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After custom field error: ' + e); + } }); type RegisterUserData = { - email: string; - password: string; + email: string; + password: string; }; function getTestData() { - const newConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); - const newConnection2 = mockFactory.generateCreateConnectionDto2(); - const newConnectionToTestDB = mockFactory.generateCreateConnectionDtoToTEstDB(); - const updateConnection = mockFactory.generateUpdateConnectionDto(); - const newGroup1 = mockFactory.generateCreateGroupDto1(); - return { - newConnection, - newConnection2, - newConnectionToTestDB, - updateConnection, - newGroup1, - }; + const newConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); + const newConnection2 = mockFactory.generateCreateConnectionDto2(); + const newConnectionToTestDB = mockFactory.generateCreateConnectionDtoToTEstDB(); + const updateConnection = mockFactory.generateUpdateConnectionDto(); + const newGroup1 = mockFactory.generateCreateGroupDto1(); + return { + newConnection, + newConnection2, + newConnectionToTestDB, + updateConnection, + newGroup1, + }; } currentTest = 'POST /connection/properties/:slug'; test.serial(`${currentTest} should return created connection properties`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${createConnectionRO.id}`) - .send(newConnectionProperties) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); - t.is(createConnectionPropertiesResponse.status, 201); - t.is(createConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); - t.is(createConnectionPropertiesRO.connectionId, createConnectionRO.id); - t.is(createConnectionPropertiesRO.allow_ai_requests, newConnectionProperties.allow_ai_requests); - t.is(createConnectionPropertiesRO.default_showing_table, newConnectionProperties.default_showing_table); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(newConnectionProperties) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); + t.is(createConnectionPropertiesResponse.status, 201); + t.is(createConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); + t.is(createConnectionPropertiesRO.connectionId, createConnectionRO.id); + t.is(createConnectionPropertiesRO.allow_ai_requests, newConnectionProperties.allow_ai_requests); + t.is(createConnectionPropertiesRO.default_showing_table, newConnectionProperties.default_showing_table); }); test.serial(`${currentTest} should return created connection properties with table categories`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const connectionPropertiesWithCategories = { - hidden_tables: [], - logo_url: faker.internet.url(), - primary_color: faker.color.rgb(), - secondary_color: faker.color.rgb(), - hostname: faker.internet.url(), - company_name: faker.company.name(), - tables_audit: true, - human_readable_table_names: faker.datatype.boolean(), - allow_ai_requests: faker.datatype.boolean(), - default_showing_table: null, - table_categories: [ - { - category_name: 'Category 1', - category_id: 'cat-001', - category_color: '#FF5733', - tables: [testTableName], - }, - ], - }; - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${createConnectionRO.id}`) - .send(connectionPropertiesWithCategories) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); - t.is(createConnectionPropertiesResponse.status, 201); - t.is(createConnectionPropertiesRO.connectionId, createConnectionRO.id); - t.is(createConnectionPropertiesRO.allow_ai_requests, connectionPropertiesWithCategories.allow_ai_requests); - t.is(createConnectionPropertiesRO.default_showing_table, connectionPropertiesWithCategories.default_showing_table); - t.is(createConnectionPropertiesRO.table_categories.length, 1); - t.is(createConnectionPropertiesRO.table_categories[0].category_name, 'Category 1'); - t.is(createConnectionPropertiesRO.table_categories[0].tables.length, 1); - t.is(createConnectionPropertiesRO.table_categories[0].tables[0], testTableName); - - // should recreated categories on update - const updatedConnectionPropertiesWithCategories = { - hidden_tables: [], - logo_url: faker.internet.url(), - primary_color: faker.color.rgb(), - secondary_color: faker.color.rgb(), - hostname: faker.internet.url(), - company_name: faker.company.name(), - tables_audit: true, - human_readable_table_names: faker.datatype.boolean(), - allow_ai_requests: faker.datatype.boolean(), - default_showing_table: null, - table_categories: [ - { - category_name: 'Updated Category', - tables: [testTableName], - category_color: '#33FF57', - category_id: 'cat-002', - }, - ], - }; - - const updateConnectionPropertiesResponse = await request(app.getHttpServer()) - .put(`/connection/properties/${createConnectionRO.id}`) - .send(updatedConnectionPropertiesWithCategories) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const updateConnectionPropertiesRO = JSON.parse(updateConnectionPropertiesResponse.text); - t.is(updateConnectionPropertiesResponse.status, 200); - t.is(updateConnectionPropertiesRO.connectionId, createConnectionRO.id); - t.is(updateConnectionPropertiesRO.allow_ai_requests, updatedConnectionPropertiesWithCategories.allow_ai_requests); - t.is( - updateConnectionPropertiesRO.default_showing_table, - updatedConnectionPropertiesWithCategories.default_showing_table, - ); - t.is(updateConnectionPropertiesRO.table_categories.length, 1); - t.is(updateConnectionPropertiesRO.table_categories[0].category_name, 'Updated Category'); - t.is(updateConnectionPropertiesRO.table_categories[0].tables.length, 1); - t.is(updateConnectionPropertiesRO.table_categories[0].tables[0], testTableName); - - // should delete categories on update with empty categories - - const updatedConnectionPropertiesWithOutCategories = { - hidden_tables: [], - logo_url: faker.internet.url(), - primary_color: faker.color.rgb(), - secondary_color: faker.color.rgb(), - hostname: faker.internet.url(), - company_name: faker.company.name(), - tables_audit: true, - human_readable_table_names: faker.datatype.boolean(), - allow_ai_requests: faker.datatype.boolean(), - default_showing_table: null, - }; - const updateConnectionPropertiesResponseWithoutCategories = await request(app.getHttpServer()) - .put(`/connection/properties/${createConnectionRO.id}`) - .send(updatedConnectionPropertiesWithOutCategories) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const updateConnectionPropertiesROWithoutCategories = JSON.parse( - updateConnectionPropertiesResponseWithoutCategories.text, - ); - t.is(updateConnectionPropertiesResponseWithoutCategories.status, 200); - t.is(updateConnectionPropertiesROWithoutCategories.connectionId, createConnectionRO.id); - t.is( - updateConnectionPropertiesROWithoutCategories.allow_ai_requests, - updatedConnectionPropertiesWithOutCategories.allow_ai_requests, - ); - t.is( - updateConnectionPropertiesROWithoutCategories.default_showing_table, - updatedConnectionPropertiesWithOutCategories.default_showing_table, - ); - t.is(updateConnectionPropertiesROWithoutCategories.table_categories.length, 1); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const connectionPropertiesWithCategories = { + hidden_tables: [], + logo_url: faker.internet.url(), + primary_color: faker.color.rgb(), + secondary_color: faker.color.rgb(), + hostname: faker.internet.url(), + company_name: faker.company.name(), + tables_audit: true, + human_readable_table_names: faker.datatype.boolean(), + allow_ai_requests: faker.datatype.boolean(), + default_showing_table: null, + table_categories: [ + { + category_name: 'Category 1', + category_id: 'cat-001', + category_color: '#FF5733', + tables: [testTableName], + }, + ], + }; + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(connectionPropertiesWithCategories) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); + t.is(createConnectionPropertiesResponse.status, 201); + t.is(createConnectionPropertiesRO.connectionId, createConnectionRO.id); + t.is(createConnectionPropertiesRO.allow_ai_requests, connectionPropertiesWithCategories.allow_ai_requests); + t.is(createConnectionPropertiesRO.default_showing_table, connectionPropertiesWithCategories.default_showing_table); + t.is(createConnectionPropertiesRO.table_categories.length, 1); + t.is(createConnectionPropertiesRO.table_categories[0].category_name, 'Category 1'); + t.is(createConnectionPropertiesRO.table_categories[0].tables.length, 1); + t.is(createConnectionPropertiesRO.table_categories[0].tables[0], testTableName); + + // should recreated categories on update + const updatedConnectionPropertiesWithCategories = { + hidden_tables: [], + logo_url: faker.internet.url(), + primary_color: faker.color.rgb(), + secondary_color: faker.color.rgb(), + hostname: faker.internet.url(), + company_name: faker.company.name(), + tables_audit: true, + human_readable_table_names: faker.datatype.boolean(), + allow_ai_requests: faker.datatype.boolean(), + default_showing_table: null, + table_categories: [ + { + category_name: 'Updated Category', + tables: [testTableName], + category_color: '#33FF57', + category_id: 'cat-002', + }, + ], + }; + + const updateConnectionPropertiesResponse = await request(app.getHttpServer()) + .put(`/connection/properties/${createConnectionRO.id}`) + .send(updatedConnectionPropertiesWithCategories) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const updateConnectionPropertiesRO = JSON.parse(updateConnectionPropertiesResponse.text); + t.is(updateConnectionPropertiesResponse.status, 200); + t.is(updateConnectionPropertiesRO.connectionId, createConnectionRO.id); + t.is(updateConnectionPropertiesRO.allow_ai_requests, updatedConnectionPropertiesWithCategories.allow_ai_requests); + t.is( + updateConnectionPropertiesRO.default_showing_table, + updatedConnectionPropertiesWithCategories.default_showing_table, + ); + t.is(updateConnectionPropertiesRO.table_categories.length, 1); + t.is(updateConnectionPropertiesRO.table_categories[0].category_name, 'Updated Category'); + t.is(updateConnectionPropertiesRO.table_categories[0].tables.length, 1); + t.is(updateConnectionPropertiesRO.table_categories[0].tables[0], testTableName); + + // should delete categories on update with empty categories + + const updatedConnectionPropertiesWithOutCategories = { + hidden_tables: [], + logo_url: faker.internet.url(), + primary_color: faker.color.rgb(), + secondary_color: faker.color.rgb(), + hostname: faker.internet.url(), + company_name: faker.company.name(), + tables_audit: true, + human_readable_table_names: faker.datatype.boolean(), + allow_ai_requests: faker.datatype.boolean(), + default_showing_table: null, + }; + const updateConnectionPropertiesResponseWithoutCategories = await request(app.getHttpServer()) + .put(`/connection/properties/${createConnectionRO.id}`) + .send(updatedConnectionPropertiesWithOutCategories) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const updateConnectionPropertiesROWithoutCategories = JSON.parse( + updateConnectionPropertiesResponseWithoutCategories.text, + ); + t.is(updateConnectionPropertiesResponseWithoutCategories.status, 200); + t.is(updateConnectionPropertiesROWithoutCategories.connectionId, createConnectionRO.id); + t.is( + updateConnectionPropertiesROWithoutCategories.allow_ai_requests, + updatedConnectionPropertiesWithOutCategories.allow_ai_requests, + ); + t.is( + updateConnectionPropertiesROWithoutCategories.default_showing_table, + updatedConnectionPropertiesWithOutCategories.default_showing_table, + ); + t.is(updateConnectionPropertiesROWithoutCategories.table_categories.length, 1); }); test.serial( - `${currentTest} should return created connection properties with table categories and return created categories in get tables request`, - async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const connectionPropertiesWithCategories = { - hidden_tables: [], - logo_url: faker.internet.url(), - primary_color: faker.color.rgb(), - secondary_color: faker.color.rgb(), - hostname: faker.internet.url(), - company_name: faker.company.name(), - tables_audit: true, - human_readable_table_names: faker.datatype.boolean(), - allow_ai_requests: faker.datatype.boolean(), - default_showing_table: null, - table_categories: [ - { category_name: 'Category 1', tables: [testTableName], category_color: '#FF5733', category_id: 'cat-001' }, - ], - }; - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${createConnectionRO.id}`) - .send(connectionPropertiesWithCategories) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); - t.is(createConnectionPropertiesResponse.status, 201); - t.is(createConnectionPropertiesRO.connectionId, createConnectionRO.id); - t.is(createConnectionPropertiesRO.allow_ai_requests, connectionPropertiesWithCategories.allow_ai_requests); - t.is( - createConnectionPropertiesRO.default_showing_table, - connectionPropertiesWithCategories.default_showing_table, - ); - t.is(createConnectionPropertiesRO.table_categories.length, 1); - t.is(createConnectionPropertiesRO.table_categories[0].category_name, 'Category 1'); - t.is(createConnectionPropertiesRO.table_categories[0].tables.length, 1); - t.is(createConnectionPropertiesRO.table_categories[0].tables[0], testTableName); - - const findTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/v2/${createConnectionRO.id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - - const findTablesRO = JSON.parse(findTablesResponse.text); - t.is(findTablesResponse.status, 200); - t.is(findTablesRO.table_categories.length, 1); - t.is(findTablesRO.table_categories[0].category_name, 'Category 1'); - t.is(findTablesRO.table_categories[0].tables.length, 1); - t.is(findTablesRO.table_categories[0].tables[0], testTableName); - t.is(findTablesRO.tables.length > 0, true); - - const testTableIndex = findTablesRO.tables.findIndex((t) => t.table === testTableName); - - t.is(Object.hasOwn(findTablesRO.tables[testTableIndex], 'table'), true); - t.is(Object.hasOwn(findTablesRO.tables[testTableIndex], 'permissions'), true); - t.is(typeof findTablesRO.tables[testTableIndex].permissions, 'object'); - t.is(Object.keys(findTablesRO.tables[testTableIndex].permissions).length, 5); - t.is(findTablesRO.tables[testTableIndex].table, testTableName); - t.is(findTablesRO.tables[testTableIndex].permissions.visibility, true); - t.is(findTablesRO.tables[testTableIndex].permissions.readonly, false); - t.is(findTablesRO.tables[testTableIndex].permissions.add, true); - t.is(findTablesRO.tables[testTableIndex].permissions.delete, true); - t.is(findTablesRO.tables[testTableIndex].permissions.edit, true); - }, + `${currentTest} should return created connection properties with table categories and return created categories in get tables request`, + async (t) => { + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const connectionPropertiesWithCategories = { + hidden_tables: [], + logo_url: faker.internet.url(), + primary_color: faker.color.rgb(), + secondary_color: faker.color.rgb(), + hostname: faker.internet.url(), + company_name: faker.company.name(), + tables_audit: true, + human_readable_table_names: faker.datatype.boolean(), + allow_ai_requests: faker.datatype.boolean(), + default_showing_table: null, + table_categories: [ + { category_name: 'Category 1', tables: [testTableName], category_color: '#FF5733', category_id: 'cat-001' }, + ], + }; + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(connectionPropertiesWithCategories) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); + t.is(createConnectionPropertiesResponse.status, 201); + t.is(createConnectionPropertiesRO.connectionId, createConnectionRO.id); + t.is(createConnectionPropertiesRO.allow_ai_requests, connectionPropertiesWithCategories.allow_ai_requests); + t.is(createConnectionPropertiesRO.default_showing_table, connectionPropertiesWithCategories.default_showing_table); + t.is(createConnectionPropertiesRO.table_categories.length, 1); + t.is(createConnectionPropertiesRO.table_categories[0].category_name, 'Category 1'); + t.is(createConnectionPropertiesRO.table_categories[0].tables.length, 1); + t.is(createConnectionPropertiesRO.table_categories[0].tables[0], testTableName); + + const findTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/v2/${createConnectionRO.id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + + const findTablesRO = JSON.parse(findTablesResponse.text); + t.is(findTablesResponse.status, 200); + t.is(findTablesRO.table_categories.length, 1); + t.is(findTablesRO.table_categories[0].category_name, 'Category 1'); + t.is(findTablesRO.table_categories[0].tables.length, 1); + t.is(findTablesRO.table_categories[0].tables[0], testTableName); + t.is(findTablesRO.tables.length > 0, true); + + const testTableIndex = findTablesRO.tables.findIndex((t) => t.table === testTableName); + + t.is(Object.hasOwn(findTablesRO.tables[testTableIndex], 'table'), true); + t.is(Object.hasOwn(findTablesRO.tables[testTableIndex], 'permissions'), true); + t.is(typeof findTablesRO.tables[testTableIndex].permissions, 'object'); + t.is(Object.keys(findTablesRO.tables[testTableIndex].permissions).length, 5); + t.is(findTablesRO.tables[testTableIndex].table, testTableName); + t.is(findTablesRO.tables[testTableIndex].permissions.visibility, true); + t.is(findTablesRO.tables[testTableIndex].permissions.readonly, false); + t.is(findTablesRO.tables[testTableIndex].permissions.add, true); + t.is(findTablesRO.tables[testTableIndex].permissions.delete, true); + t.is(findTablesRO.tables[testTableIndex].permissions.edit, true); + }, ); test.serial(`${currentTest} should return connection without excluded tables`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${createConnectionRO.id}`) - .send(newConnectionProperties) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); - t.is(createConnectionPropertiesResponse.status, 201); - t.is(createConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); - t.is(createConnectionPropertiesRO.connectionId, createConnectionRO.id); - - const getConnectionTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const getConnectionTablesRO = JSON.parse(getConnectionTablesResponse.text); - t.is(getConnectionTablesRO.length > 0, true); - const hiddenTable = getConnectionTablesRO.find((table) => table.name === newConnectionProperties.hidden_tables[0]); - t.is(hiddenTable, undefined); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(newConnectionProperties) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); + t.is(createConnectionPropertiesResponse.status, 201); + t.is(createConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); + t.is(createConnectionPropertiesRO.connectionId, createConnectionRO.id); + + const getConnectionTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getConnectionTablesRO = JSON.parse(getConnectionTablesResponse.text); + t.is(getConnectionTablesRO.length > 0, true); + const hiddenTable = getConnectionTablesRO.find((table) => table.name === newConnectionProperties.hidden_tables[0]); + t.is(hiddenTable, undefined); }); test.serial(`${currentTest} should throw an exception when excluded table name is incorrect`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const copyNewConnectionResponse = JSON.parse(JSON.stringify(newConnectionProperties)); - copyNewConnectionResponse.hidden_tables[0] = `${faker.lorem.words(1)}_${faker.number.int({ - min: 1, - max: 10000, - })}`; - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${createConnectionRO.id}`) - .send(copyNewConnectionResponse) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const _createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); - t.is(createConnectionPropertiesResponse.status, 400); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const copyNewConnectionResponse = JSON.parse(JSON.stringify(newConnectionProperties)); + copyNewConnectionResponse.hidden_tables[0] = `${faker.lorem.words(1)}_${faker.number.int({ + min: 1, + max: 10000, + })}`; + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(copyNewConnectionResponse) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const _createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); + t.is(createConnectionPropertiesResponse.status, 400); }); currentTest = 'GET /connection/properties/:slug'; test.serial(`${currentTest} should return connection properties`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${createConnectionRO.id}`) - .send(newConnectionProperties) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionPropertiesResponse.status, 201); - - const getConnectionPropertiesResponse = await request(app.getHttpServer()) - .get(`/connection/properties/${createConnectionRO.id}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getConnectionPropertiesRO = JSON.parse(getConnectionPropertiesResponse.text); - t.is(getConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); - t.is(getConnectionPropertiesRO.connectionId, createConnectionRO.id); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(newConnectionProperties) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionPropertiesResponse.status, 201); + + const getConnectionPropertiesResponse = await request(app.getHttpServer()) + .get(`/connection/properties/${createConnectionRO.id}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getConnectionPropertiesRO = JSON.parse(getConnectionPropertiesResponse.text); + t.is(getConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); + t.is(getConnectionPropertiesRO.connectionId, createConnectionRO.id); }); test.serial(`${currentTest} should throw exception when connection id is incorrect`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${createConnectionRO.id}`) - .send(newConnectionProperties) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionPropertiesResponse.status, 201); - - const getConnectionPropertiesResponse = await request(app.getHttpServer()) - .get(`/connection/properties/${faker.string.uuid()}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getConnectionPropertiesResponse.status, 403); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(newConnectionProperties) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionPropertiesResponse.status, 201); + + const getConnectionPropertiesResponse = await request(app.getHttpServer()) + .get(`/connection/properties/${faker.string.uuid()}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getConnectionPropertiesResponse.status, 403); }); currentTest = 'DELETE /connection/properties/:slug'; test.serial(`${currentTest} should return deleted connection properties`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${createConnectionRO.id}`) - .send(newConnectionProperties) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionPropertiesResponse.status, 201); - - const getConnectionPropertiesResponse = await request(app.getHttpServer()) - .get(`/connection/properties/${createConnectionRO.id}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionPropertiesResponse.status, 201); - - const getConnectionPropertiesRO = JSON.parse(getConnectionPropertiesResponse.text); - t.is(getConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); - t.is(getConnectionPropertiesRO.connectionId, createConnectionRO.id); - - const deleteConnectionPropertiesResponse = await request(app.getHttpServer()) - .delete(`/connection/properties/${createConnectionRO.id}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(deleteConnectionPropertiesResponse.status, 200); - const deleteConnectionPropertiesRO = JSON.parse(deleteConnectionPropertiesResponse.text); - - t.is(deleteConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); - - const getConnectionPropertiesResponseAfterDeletion = await request(app.getHttpServer()) - .get(`/connection/properties/${createConnectionRO.id}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionPropertiesResponse.status, 201); - const _getConnectionPropertiesAfterDeletionRO = getConnectionPropertiesResponseAfterDeletion.text; + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(newConnectionProperties) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionPropertiesResponse.status, 201); + + const getConnectionPropertiesResponse = await request(app.getHttpServer()) + .get(`/connection/properties/${createConnectionRO.id}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionPropertiesResponse.status, 201); + + const getConnectionPropertiesRO = JSON.parse(getConnectionPropertiesResponse.text); + t.is(getConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); + t.is(getConnectionPropertiesRO.connectionId, createConnectionRO.id); + + const deleteConnectionPropertiesResponse = await request(app.getHttpServer()) + .delete(`/connection/properties/${createConnectionRO.id}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(deleteConnectionPropertiesResponse.status, 200); + const deleteConnectionPropertiesRO = JSON.parse(deleteConnectionPropertiesResponse.text); + + t.is(deleteConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); + + const getConnectionPropertiesResponseAfterDeletion = await request(app.getHttpServer()) + .get(`/connection/properties/${createConnectionRO.id}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionPropertiesResponse.status, 201); + const _getConnectionPropertiesAfterDeletionRO = getConnectionPropertiesResponseAfterDeletion.text; }); test.serial(`${currentTest} should throw exception when connection id is incorrect`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${createConnectionRO.id}`) - .send(newConnectionProperties) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionPropertiesResponse.status, 201); - - const getConnectionPropertiesResponse = await request(app.getHttpServer()) - .get(`/connection/properties/${faker.string.uuid()}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getConnectionPropertiesResponse.status, 403); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(newConnectionProperties) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionPropertiesResponse.status, 201); + + const getConnectionPropertiesResponse = await request(app.getHttpServer()) + .get(`/connection/properties/${faker.string.uuid()}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getConnectionPropertiesResponse.status, 403); }); currentTest = 'PUT /connection/properties/:slug'; test.serial(`${currentTest} should return updated connection properties`, async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${createConnectionRO.id}`) - .send(newConnectionProperties) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); - t.is(createConnectionPropertiesResponse.status, 201); - t.is(createConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); - t.is(createConnectionPropertiesRO.connectionId, createConnectionRO.id); + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(newConnectionProperties) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); + t.is(createConnectionPropertiesResponse.status, 201); + t.is(createConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); + t.is(createConnectionPropertiesRO.connectionId, createConnectionRO.id); }); test.serial( - `${currentTest} should keep created table categories if the exists return updated connection properties`, - async (t) => { - const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); - const { token } = await registerUserAndReturnUserInfo(app); - const secondHiddenTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - await resetPostgresTestDB(secondHiddenTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${createConnectionRO.id}`) - .send(newConnectionProperties) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); - t.is(createConnectionPropertiesResponse.status, 201); - t.is(createConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); - t.is(createConnectionPropertiesRO.connectionId, createConnectionRO.id); - - const categoriesDTO: Array = [ - { - category_name: 'Category 1', - category_color: '#FF5733', - tables: [testTableName], - category_id: 'cat-001', - }, - ]; - - const createTableCategoriesResponse = await request(app.getHttpServer()) - .put(`/table-categories/${createConnectionRO.id}`) - .send(categoriesDTO) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _createTableCategoriesRO = JSON.parse(createTableCategoriesResponse.text); - - t.is(createTableCategoriesResponse.status, 200); - - const propertiesCopy = JSON.parse(JSON.stringify(newConnectionProperties)); - propertiesCopy.hidden_tables = [testTableName, secondHiddenTableName]; - - const updateConnectionPropertiesResponse = await request(app.getHttpServer()) - .put(`/connection/properties/${createConnectionRO.id}`) - .send(propertiesCopy) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateConnectionPropertiesResponse.status, 200); - - const updateConnectionPropertiesRO = JSON.parse(updateConnectionPropertiesResponse.text); - t.is(updateConnectionPropertiesRO.hidden_tables.length, 2); - t.is(updateConnectionPropertiesRO.hidden_tables.includes(testTableName), true); - t.is(updateConnectionPropertiesRO.hidden_tables.includes(secondHiddenTableName), true); - t.is(updateConnectionPropertiesRO.connectionId, createConnectionRO.id); - t.is(updateConnectionPropertiesRO.table_categories.length, 1); - t.is(updateConnectionPropertiesRO.table_categories[0].category_name, 'Category 1'); - t.is(updateConnectionPropertiesRO.table_categories[0].tables.length, 1); - t.is(updateConnectionPropertiesRO.table_categories[0].tables[0], testTableName); - - const findTableCategoriesResponse = await request(app.getHttpServer()) - .get(`/table-categories/${createConnectionRO.id}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const findTableCategoriesRO = JSON.parse(findTableCategoriesResponse.text); - - t.is(findTableCategoriesResponse.status, 200); - - t.is(findTableCategoriesRO.length, 1); - t.is(findTableCategoriesRO[0].category_name, 'Category 1'); - t.is(findTableCategoriesRO[0].tables.length, 1); - t.is(findTableCategoriesRO[0].tables[0], testTableName); - }, + `${currentTest} should keep created table categories if the exists return updated connection properties`, + async (t) => { + const { newConnection2, newConnectionToTestDB, updateConnection, newGroup1, newConnection } = getTestData(); + const { token } = await registerUserAndReturnUserInfo(app); + const secondHiddenTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + await resetPostgresTestDB(secondHiddenTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${createConnectionRO.id}`) + .send(newConnectionProperties) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); + t.is(createConnectionPropertiesResponse.status, 201); + t.is(createConnectionPropertiesRO.hidden_tables[0], newConnectionProperties.hidden_tables[0]); + t.is(createConnectionPropertiesRO.connectionId, createConnectionRO.id); + + const categoriesDTO: Array = [ + { + category_name: 'Category 1', + category_color: '#FF5733', + tables: [testTableName], + category_id: 'cat-001', + }, + ]; + + const createTableCategoriesResponse = await request(app.getHttpServer()) + .put(`/table-categories/${createConnectionRO.id}`) + .send(categoriesDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _createTableCategoriesRO = JSON.parse(createTableCategoriesResponse.text); + + t.is(createTableCategoriesResponse.status, 200); + + const propertiesCopy = JSON.parse(JSON.stringify(newConnectionProperties)); + propertiesCopy.hidden_tables = [testTableName, secondHiddenTableName]; + + const updateConnectionPropertiesResponse = await request(app.getHttpServer()) + .put(`/connection/properties/${createConnectionRO.id}`) + .send(propertiesCopy) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateConnectionPropertiesResponse.status, 200); + + const updateConnectionPropertiesRO = JSON.parse(updateConnectionPropertiesResponse.text); + t.is(updateConnectionPropertiesRO.hidden_tables.length, 2); + t.is(updateConnectionPropertiesRO.hidden_tables.includes(testTableName), true); + t.is(updateConnectionPropertiesRO.hidden_tables.includes(secondHiddenTableName), true); + t.is(updateConnectionPropertiesRO.connectionId, createConnectionRO.id); + t.is(updateConnectionPropertiesRO.table_categories.length, 1); + t.is(updateConnectionPropertiesRO.table_categories[0].category_name, 'Category 1'); + t.is(updateConnectionPropertiesRO.table_categories[0].tables.length, 1); + t.is(updateConnectionPropertiesRO.table_categories[0].tables[0], testTableName); + + const findTableCategoriesResponse = await request(app.getHttpServer()) + .get(`/table-categories/${createConnectionRO.id}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const findTableCategoriesRO = JSON.parse(findTableCategoriesResponse.text); + + t.is(findTableCategoriesResponse.status, 200); + + t.is(findTableCategoriesRO.length, 1); + t.is(findTableCategoriesRO[0].category_name, 'Category 1'); + t.is(findTableCategoriesRO[0].tables.length, 1); + t.is(findTableCategoriesRO[0].tables[0], testTableName); + }, ); diff --git a/backend/test/ava-tests/saas-tests/custom-domains-e2e.test.ts b/backend/test/ava-tests/saas-tests/custom-domains-e2e.test.ts index 5f4104b49..3e6e4186e 100644 --- a/backend/test/ava-tests/saas-tests/custom-domains-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/custom-domains-e2e.test.ts @@ -28,58 +28,58 @@ let currentTest: string; // custom domains test (available only in saas mode) test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication() as any; - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); - - // nock('https://api.stripe.com') - // .get(`/.*/`) - // .reply(200, (uri, requestBody) => { - // console.log('\nNOCK CALLED\n'); - // return { - // object: 'list', - // data: [ - // { - // items: [ - // { - // data: [ - // { - // price: { - // id: 'annual_team_test', - // }, - // }, - // ], - // }, - // ], - // }, - // ], - // }; - // }); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication() as any; + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); + + // nock('https://api.stripe.com') + // .get(`/.*/`) + // .reply(200, (uri, requestBody) => { + // console.log('\nNOCK CALLED\n'); + // return { + // object: 'list', + // data: [ + // { + // items: [ + // { + // data: [ + // { + // price: { + // id: 'annual_team_test', + // }, + // }, + // ], + // }, + // ], + // }, + // ], + // }; + // }); }); test.after(async () => { - try { - // nock.cleanAll(); - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After custom field error: ' + e); - } + try { + // nock.cleanAll(); + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After custom field error: ' + e); + } }); // test.beforeEach(async () => { @@ -88,464 +88,464 @@ test.after(async () => { currentTest = 'POST custom-domain/register/:companyId'; test.serial(`${currentTest} - should return registered custom domain`, async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const foundCompanyInfo = await request(app.getHttpServer()) - .get('/company/my') - .set('Content-Type', 'application/json') - .set('Cookie', simpleUserToken) - .set('Accept', 'application/json'); - - t.is(foundCompanyInfo.status, 200); - const foundCompanyInfoRO = JSON.parse(foundCompanyInfo.text); - - const companyId = foundCompanyInfoRO.id; - const customDomain = faker.internet.domainName(); - const requestDomainData = { - hostname: customDomain, - }; - const registerDomainResponse = await sendRequestToSaasPart( - `custom-domain/register/${companyId}`, - 'POST', - requestDomainData, - adminUserToken, - ); - const registerDomainResponseRO = await registerDomainResponse.json(); - t.is(registerDomainResponse.status, 201); - - t.is(registerDomainResponseRO.hostname, customDomain); - t.is(registerDomainResponseRO.companyId, companyId); - t.is(Object.hasOwn(registerDomainResponseRO, 'id'), true); - t.is(Object.hasOwn(registerDomainResponseRO, 'createdAt'), true); - t.is(Object.keys(registerDomainResponseRO).length, 5); - } catch (error) { - t.fail(error.message); - } + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const foundCompanyInfo = await request(app.getHttpServer()) + .get('/company/my') + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + + t.is(foundCompanyInfo.status, 200); + const foundCompanyInfoRO = JSON.parse(foundCompanyInfo.text); + + const companyId = foundCompanyInfoRO.id; + const customDomain = faker.internet.domainName(); + const requestDomainData = { + hostname: customDomain, + }; + const registerDomainResponse = await sendRequestToSaasPart( + `custom-domain/register/${companyId}`, + 'POST', + requestDomainData, + adminUserToken, + ); + const registerDomainResponseRO = await registerDomainResponse.json(); + t.is(registerDomainResponse.status, 201); + + t.is(registerDomainResponseRO.hostname, customDomain); + t.is(registerDomainResponseRO.companyId, companyId); + t.is(Object.hasOwn(registerDomainResponseRO, 'id'), true); + t.is(Object.hasOwn(registerDomainResponseRO, 'createdAt'), true); + t.is(Object.keys(registerDomainResponseRO).length, 5); + } catch (error) { + t.fail(error.message); + } }); test.serial(`${currentTest} - should throw exception when hostname is incorrect`, async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const foundCompanyInfo = await request(app.getHttpServer()) - .get('/company/my') - .set('Content-Type', 'application/json') - .set('Cookie', simpleUserToken) - .set('Accept', 'application/json'); - - t.is(foundCompanyInfo.status, 200); - const foundCompanyInfoRO = JSON.parse(foundCompanyInfo.text); - - const companyId = foundCompanyInfoRO.id; - - const requestDomainData = { - hostname: 'incorrect-domain', - }; - const registerDomainResponse = await sendRequestToSaasPart( - `custom-domain/register/${companyId}`, - 'POST', - requestDomainData, - adminUserToken, - ); - t.is(registerDomainResponse.status, 400); - } catch (error) { - t.fail(error.message); - } + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const foundCompanyInfo = await request(app.getHttpServer()) + .get('/company/my') + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + + t.is(foundCompanyInfo.status, 200); + const foundCompanyInfoRO = JSON.parse(foundCompanyInfo.text); + + const companyId = foundCompanyInfoRO.id; + + const requestDomainData = { + hostname: 'incorrect-domain', + }; + const registerDomainResponse = await sendRequestToSaasPart( + `custom-domain/register/${companyId}`, + 'POST', + requestDomainData, + adminUserToken, + ); + t.is(registerDomainResponse.status, 400); + } catch (error) { + t.fail(error.message); + } }); currentTest = 'GET custom-domain/:companyId'; test.serial(`${currentTest} - should return found custom domain`, async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const foundCompanyInfo = await request(app.getHttpServer()) - .get('/company/my') - .set('Content-Type', 'application/json') - .set('Cookie', simpleUserToken) - .set('Accept', 'application/json'); - - t.is(foundCompanyInfo.status, 200); - const foundCompanyInfoRO = JSON.parse(foundCompanyInfo.text); - - const companyId = foundCompanyInfoRO.id; - const customDomain = faker.internet.domainName(); - const requestDomainData = { - hostname: customDomain, - }; - const registerDomainResponse = await sendRequestToSaasPart( - `custom-domain/register/${companyId}`, - 'POST', - requestDomainData, - adminUserToken, - ); - t.is(registerDomainResponse.status, 201); - const registerDomainResponseRO = await registerDomainResponse.json(); - - t.is(registerDomainResponseRO.hostname, customDomain); - t.is(registerDomainResponseRO.companyId, companyId); - t.is(Object.hasOwn(registerDomainResponseRO, 'id'), true); - t.is(Object.hasOwn(registerDomainResponseRO, 'createdAt'), true); - t.is(Object.keys(registerDomainResponseRO).length, 5); - - const foundDomainResponse = await sendRequestToSaasPart( - `custom-domain/${companyId}`, - 'GET', - undefined, - adminUserToken, - ); - t.is(foundDomainResponse.status, 200); - const foundDomainResponseRO = await foundDomainResponse.json(); - t.is(Object.hasOwn(foundDomainResponseRO, 'success'), true); - t.is(Object.hasOwn(foundDomainResponseRO, 'domain_info'), true); - - const domainInfo = foundDomainResponseRO.domain_info; - - t.is(domainInfo.hostname, customDomain); - t.is(domainInfo.companyId, companyId); - t.is(Object.hasOwn(domainInfo, 'id'), true); - t.is(Object.hasOwn(domainInfo, 'createdAt'), true); - t.is(Object.keys(domainInfo).length, 5); - - const foundCompanyFullInfoResponse = await request(app.getHttpServer()) - .get('/company/my/full') - .set('Content-Type', 'application/json') - .set('Cookie', simpleUserToken) - .set('Accept', 'application/json'); - - t.is(foundCompanyFullInfoResponse.status, 200); - const foundCompanyFullInfoResponseRO = JSON.parse(foundCompanyFullInfoResponse.text); - t.is(Object.hasOwn(foundCompanyFullInfoResponseRO, 'custom_domain'), true); - t.is(foundCompanyFullInfoResponseRO.custom_domain, requestDomainData.hostname); - } catch (error) { - t.fail(error.message); - } + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const foundCompanyInfo = await request(app.getHttpServer()) + .get('/company/my') + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + + t.is(foundCompanyInfo.status, 200); + const foundCompanyInfoRO = JSON.parse(foundCompanyInfo.text); + + const companyId = foundCompanyInfoRO.id; + const customDomain = faker.internet.domainName(); + const requestDomainData = { + hostname: customDomain, + }; + const registerDomainResponse = await sendRequestToSaasPart( + `custom-domain/register/${companyId}`, + 'POST', + requestDomainData, + adminUserToken, + ); + t.is(registerDomainResponse.status, 201); + const registerDomainResponseRO = await registerDomainResponse.json(); + + t.is(registerDomainResponseRO.hostname, customDomain); + t.is(registerDomainResponseRO.companyId, companyId); + t.is(Object.hasOwn(registerDomainResponseRO, 'id'), true); + t.is(Object.hasOwn(registerDomainResponseRO, 'createdAt'), true); + t.is(Object.keys(registerDomainResponseRO).length, 5); + + const foundDomainResponse = await sendRequestToSaasPart( + `custom-domain/${companyId}`, + 'GET', + undefined, + adminUserToken, + ); + t.is(foundDomainResponse.status, 200); + const foundDomainResponseRO = await foundDomainResponse.json(); + t.is(Object.hasOwn(foundDomainResponseRO, 'success'), true); + t.is(Object.hasOwn(foundDomainResponseRO, 'domain_info'), true); + + const domainInfo = foundDomainResponseRO.domain_info; + + t.is(domainInfo.hostname, customDomain); + t.is(domainInfo.companyId, companyId); + t.is(Object.hasOwn(domainInfo, 'id'), true); + t.is(Object.hasOwn(domainInfo, 'createdAt'), true); + t.is(Object.keys(domainInfo).length, 5); + + const foundCompanyFullInfoResponse = await request(app.getHttpServer()) + .get('/company/my/full') + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + + t.is(foundCompanyFullInfoResponse.status, 200); + const foundCompanyFullInfoResponseRO = JSON.parse(foundCompanyFullInfoResponse.text); + t.is(Object.hasOwn(foundCompanyFullInfoResponseRO, 'custom_domain'), true); + t.is(foundCompanyFullInfoResponseRO.custom_domain, requestDomainData.hostname); + } catch (error) { + t.fail(error.message); + } }); test.serial(`${currentTest} - should throw exception when company id is invalid`, async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const foundCompanyInfo = await request(app.getHttpServer()) - .get('/company/my') - .set('Content-Type', 'application/json') - .set('Cookie', simpleUserToken) - .set('Accept', 'application/json'); - - t.is(foundCompanyInfo.status, 200); - const foundCompanyInfoRO = JSON.parse(foundCompanyInfo.text); - - const companyId = foundCompanyInfoRO.id; - const customDomain = faker.internet.domainName(); - const requestDomainData = { - hostname: customDomain, - }; - const registerDomainResponse = await sendRequestToSaasPart( - `custom-domain/register/${companyId}`, - 'POST', - requestDomainData, - adminUserToken, - ); - t.is(registerDomainResponse.status, 201); - const registerDomainResponseRO = await registerDomainResponse.json(); - - t.is(registerDomainResponseRO.hostname, customDomain); - t.is(registerDomainResponseRO.companyId, companyId); - t.is(Object.hasOwn(registerDomainResponseRO, 'id'), true); - t.is(Object.hasOwn(registerDomainResponseRO, 'createdAt'), true); - t.is(Object.keys(registerDomainResponseRO).length, 5); - - const foundDomainResponse = await sendRequestToSaasPart( - `custom-domain/${faker.string.uuid()}`, - 'GET', - undefined, - adminUserToken, - ); - t.is(foundDomainResponse.status, 404); - } catch (error) { - t.fail(error.message); - } + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const foundCompanyInfo = await request(app.getHttpServer()) + .get('/company/my') + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + + t.is(foundCompanyInfo.status, 200); + const foundCompanyInfoRO = JSON.parse(foundCompanyInfo.text); + + const companyId = foundCompanyInfoRO.id; + const customDomain = faker.internet.domainName(); + const requestDomainData = { + hostname: customDomain, + }; + const registerDomainResponse = await sendRequestToSaasPart( + `custom-domain/register/${companyId}`, + 'POST', + requestDomainData, + adminUserToken, + ); + t.is(registerDomainResponse.status, 201); + const registerDomainResponseRO = await registerDomainResponse.json(); + + t.is(registerDomainResponseRO.hostname, customDomain); + t.is(registerDomainResponseRO.companyId, companyId); + t.is(Object.hasOwn(registerDomainResponseRO, 'id'), true); + t.is(Object.hasOwn(registerDomainResponseRO, 'createdAt'), true); + t.is(Object.keys(registerDomainResponseRO).length, 5); + + const foundDomainResponse = await sendRequestToSaasPart( + `custom-domain/${faker.string.uuid()}`, + 'GET', + undefined, + adminUserToken, + ); + t.is(foundDomainResponse.status, 404); + } catch (error) { + t.fail(error.message); + } }); currentTest = 'PUT custom-domain/update/:companyId'; test.serial(`${currentTest} - should return updated custom domain`, async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const foundCompanyInfo = await request(app.getHttpServer()) - .get('/company/my') - .set('Content-Type', 'application/json') - .set('Cookie', simpleUserToken) - .set('Accept', 'application/json'); - - t.is(foundCompanyInfo.status, 200); - const foundCompanyInfoRO = JSON.parse(foundCompanyInfo.text); - - const companyId = foundCompanyInfoRO.id; - const customDomain = faker.internet.domainName(); - const requestDomainData = { - hostname: customDomain, - }; - const registerDomainResponse = await sendRequestToSaasPart( - `custom-domain/register/${companyId}`, - 'POST', - requestDomainData, - adminUserToken, - ); - t.is(registerDomainResponse.status, 201); - const registerDomainResponseRO = await registerDomainResponse.json(); - - t.is(registerDomainResponseRO.hostname, customDomain); - t.is(registerDomainResponseRO.companyId, companyId); - t.is(Object.hasOwn(registerDomainResponseRO, 'id'), true); - t.is(Object.hasOwn(registerDomainResponseRO, 'createdAt'), true); - t.is(Object.keys(registerDomainResponseRO).length, 5); - - const updatedCustomDomain = faker.internet.domainName(); - const updateDomainData = { - hostname: updatedCustomDomain, - }; - const updateDomainResponse = await sendRequestToSaasPart( - `custom-domain/update/${companyId}`, - 'PUT', - updateDomainData, - adminUserToken, - ); - - const updateDomainResponseRO = await updateDomainResponse.json(); - t.is(updateDomainResponse.status, 200); - t.is(updateDomainResponseRO.hostname, updatedCustomDomain); - t.is(updateDomainResponseRO.companyId, companyId); - t.is(Object.hasOwn(updateDomainResponseRO, 'id'), true); - t.is(Object.hasOwn(updateDomainResponseRO, 'createdAt'), true); - t.is(Object.hasOwn(updateDomainResponseRO, 'updatedAt'), true); - t.is(Object.keys(updateDomainResponseRO).length, 5); - } catch (error) { - t.fail(error.message); - } + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const foundCompanyInfo = await request(app.getHttpServer()) + .get('/company/my') + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + + t.is(foundCompanyInfo.status, 200); + const foundCompanyInfoRO = JSON.parse(foundCompanyInfo.text); + + const companyId = foundCompanyInfoRO.id; + const customDomain = faker.internet.domainName(); + const requestDomainData = { + hostname: customDomain, + }; + const registerDomainResponse = await sendRequestToSaasPart( + `custom-domain/register/${companyId}`, + 'POST', + requestDomainData, + adminUserToken, + ); + t.is(registerDomainResponse.status, 201); + const registerDomainResponseRO = await registerDomainResponse.json(); + + t.is(registerDomainResponseRO.hostname, customDomain); + t.is(registerDomainResponseRO.companyId, companyId); + t.is(Object.hasOwn(registerDomainResponseRO, 'id'), true); + t.is(Object.hasOwn(registerDomainResponseRO, 'createdAt'), true); + t.is(Object.keys(registerDomainResponseRO).length, 5); + + const updatedCustomDomain = faker.internet.domainName(); + const updateDomainData = { + hostname: updatedCustomDomain, + }; + const updateDomainResponse = await sendRequestToSaasPart( + `custom-domain/update/${companyId}`, + 'PUT', + updateDomainData, + adminUserToken, + ); + + const updateDomainResponseRO = await updateDomainResponse.json(); + t.is(updateDomainResponse.status, 200); + t.is(updateDomainResponseRO.hostname, updatedCustomDomain); + t.is(updateDomainResponseRO.companyId, companyId); + t.is(Object.hasOwn(updateDomainResponseRO, 'id'), true); + t.is(Object.hasOwn(updateDomainResponseRO, 'createdAt'), true); + t.is(Object.hasOwn(updateDomainResponseRO, 'updatedAt'), true); + t.is(Object.keys(updateDomainResponseRO).length, 5); + } catch (error) { + t.fail(error.message); + } }); test.serial(`${currentTest} - should throw exception when hostname is invalid`, async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const foundCompanyInfo = await request(app.getHttpServer()) - .get('/company/my') - .set('Content-Type', 'application/json') - .set('Cookie', simpleUserToken) - .set('Accept', 'application/json'); - - t.is(foundCompanyInfo.status, 200); - const foundCompanyInfoRO = JSON.parse(foundCompanyInfo.text); - - const companyId = foundCompanyInfoRO.id; - const customDomain = faker.internet.domainName(); - const requestDomainData = { - hostname: customDomain, - }; - const registerDomainResponse = await sendRequestToSaasPart( - `custom-domain/register/${companyId}`, - 'POST', - requestDomainData, - adminUserToken, - ); - - const registerDomainResponseRO = await registerDomainResponse.json(); - t.is(registerDomainResponse.status, 201); - t.is(registerDomainResponseRO.hostname, customDomain); - t.is(registerDomainResponseRO.companyId, companyId); - t.is(Object.hasOwn(registerDomainResponseRO, 'id'), true); - t.is(Object.hasOwn(registerDomainResponseRO, 'createdAt'), true); - t.is(Object.keys(registerDomainResponseRO).length, 5); - - const updateDomainData = { - hostname: 'incorrect-domain', - }; - const updateDomainResponse = await sendRequestToSaasPart( - `custom-domain/update/${companyId}`, - 'PUT', - updateDomainData, - adminUserToken, - ); - t.is(updateDomainResponse.status, 400); - } catch (error) { - t.fail(error.message); - } + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const foundCompanyInfo = await request(app.getHttpServer()) + .get('/company/my') + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + + t.is(foundCompanyInfo.status, 200); + const foundCompanyInfoRO = JSON.parse(foundCompanyInfo.text); + + const companyId = foundCompanyInfoRO.id; + const customDomain = faker.internet.domainName(); + const requestDomainData = { + hostname: customDomain, + }; + const registerDomainResponse = await sendRequestToSaasPart( + `custom-domain/register/${companyId}`, + 'POST', + requestDomainData, + adminUserToken, + ); + + const registerDomainResponseRO = await registerDomainResponse.json(); + t.is(registerDomainResponse.status, 201); + t.is(registerDomainResponseRO.hostname, customDomain); + t.is(registerDomainResponseRO.companyId, companyId); + t.is(Object.hasOwn(registerDomainResponseRO, 'id'), true); + t.is(Object.hasOwn(registerDomainResponseRO, 'createdAt'), true); + t.is(Object.keys(registerDomainResponseRO).length, 5); + + const updateDomainData = { + hostname: 'incorrect-domain', + }; + const updateDomainResponse = await sendRequestToSaasPart( + `custom-domain/update/${companyId}`, + 'PUT', + updateDomainData, + adminUserToken, + ); + t.is(updateDomainResponse.status, 400); + } catch (error) { + t.fail(error.message); + } }); test.serial(`${currentTest} - should throw exception when company id is incorrect`, async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const foundCompanyInfo = await request(app.getHttpServer()) - .get('/company/my') - .set('Content-Type', 'application/json') - .set('Cookie', simpleUserToken) - .set('Accept', 'application/json'); - - t.is(foundCompanyInfo.status, 200); - const foundCompanyInfoRO = JSON.parse(foundCompanyInfo.text); - - const companyId = foundCompanyInfoRO.id; - const customDomain = faker.internet.domainName(); - const requestDomainData = { - hostname: customDomain, - }; - const registerDomainResponse = await sendRequestToSaasPart( - `custom-domain/register/${companyId}`, - 'POST', - requestDomainData, - adminUserToken, - ); - t.is(registerDomainResponse.status, 201); - const registerDomainResponseRO = await registerDomainResponse.json(); - - t.is(registerDomainResponseRO.hostname, customDomain); - t.is(registerDomainResponseRO.companyId, companyId); - t.is(Object.hasOwn(registerDomainResponseRO, 'id'), true); - t.is(Object.hasOwn(registerDomainResponseRO, 'createdAt'), true); - t.is(Object.keys(registerDomainResponseRO).length, 5); - - const updatedCustomDomain = faker.internet.domainName(); - const updateDomainData = { - hostname: updatedCustomDomain, - }; - const updateDomainResponse = await sendRequestToSaasPart( - `custom-domain/update/${registerDomainResponseRO.id}/${faker.string.uuid()}`, - 'PUT', - updateDomainData, - adminUserToken, - ); - t.is(updateDomainResponse.status, 404); - } catch (error) { - t.fail(error.message); - } + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const foundCompanyInfo = await request(app.getHttpServer()) + .get('/company/my') + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + + t.is(foundCompanyInfo.status, 200); + const foundCompanyInfoRO = JSON.parse(foundCompanyInfo.text); + + const companyId = foundCompanyInfoRO.id; + const customDomain = faker.internet.domainName(); + const requestDomainData = { + hostname: customDomain, + }; + const registerDomainResponse = await sendRequestToSaasPart( + `custom-domain/register/${companyId}`, + 'POST', + requestDomainData, + adminUserToken, + ); + t.is(registerDomainResponse.status, 201); + const registerDomainResponseRO = await registerDomainResponse.json(); + + t.is(registerDomainResponseRO.hostname, customDomain); + t.is(registerDomainResponseRO.companyId, companyId); + t.is(Object.hasOwn(registerDomainResponseRO, 'id'), true); + t.is(Object.hasOwn(registerDomainResponseRO, 'createdAt'), true); + t.is(Object.keys(registerDomainResponseRO).length, 5); + + const updatedCustomDomain = faker.internet.domainName(); + const updateDomainData = { + hostname: updatedCustomDomain, + }; + const updateDomainResponse = await sendRequestToSaasPart( + `custom-domain/update/${registerDomainResponseRO.id}/${faker.string.uuid()}`, + 'PUT', + updateDomainData, + adminUserToken, + ); + t.is(updateDomainResponse.status, 404); + } catch (error) { + t.fail(error.message); + } }); currentTest = 'DELETE custom-domain/delete/:companyId'; test.serial(`${currentTest} - should delete custom domain`, async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const foundCompanyInfo = await request(app.getHttpServer()) - .get('/company/my') - .set('Content-Type', 'application/json') - .set('Cookie', simpleUserToken) - .set('Accept', 'application/json'); - - t.is(foundCompanyInfo.status, 200); - const foundCompanyInfoRO = JSON.parse(foundCompanyInfo.text); - - const companyId = foundCompanyInfoRO.id; - const customDomain = faker.internet.domainName(); - const requestDomainData = { - hostname: customDomain, - }; - const registerDomainResponse = await sendRequestToSaasPart( - `custom-domain/register/${companyId}`, - 'POST', - requestDomainData, - adminUserToken, - ); - t.is(registerDomainResponse.status, 201); - const registerDomainResponseRO = await registerDomainResponse.json(); - - t.is(registerDomainResponseRO.hostname, customDomain); - t.is(registerDomainResponseRO.companyId, companyId); - t.is(Object.hasOwn(registerDomainResponseRO, 'id'), true); - t.is(Object.hasOwn(registerDomainResponseRO, 'createdAt'), true); - t.is(Object.keys(registerDomainResponseRO).length, 5); - - const deleteDomainResponse = await sendRequestToSaasPart( - `custom-domain/delete/${companyId}`, - 'DELETE', - undefined, - adminUserToken, - ); - t.is(deleteDomainResponse.status, 200); - const deleteDomainResponseRO = await deleteDomainResponse.json(); - t.is(deleteDomainResponseRO.success, true); - - // check that domain was deleted - - const foundDomainResponse = await sendRequestToSaasPart( - `custom-domain/${companyId}`, - 'GET', - undefined, - adminUserToken, - ); - - const foundDomainResponseRO = await foundDomainResponse.json(); - t.is(Object.hasOwn(foundDomainResponseRO, 'success'), true); - t.is(foundDomainResponseRO.success, false); - t.is(Object.hasOwn(foundDomainResponseRO, 'domain_info'), true); - t.is(foundDomainResponseRO.domain_info, null); - } catch (error) { - t.fail(error.message); - } + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const foundCompanyInfo = await request(app.getHttpServer()) + .get('/company/my') + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + + t.is(foundCompanyInfo.status, 200); + const foundCompanyInfoRO = JSON.parse(foundCompanyInfo.text); + + const companyId = foundCompanyInfoRO.id; + const customDomain = faker.internet.domainName(); + const requestDomainData = { + hostname: customDomain, + }; + const registerDomainResponse = await sendRequestToSaasPart( + `custom-domain/register/${companyId}`, + 'POST', + requestDomainData, + adminUserToken, + ); + t.is(registerDomainResponse.status, 201); + const registerDomainResponseRO = await registerDomainResponse.json(); + + t.is(registerDomainResponseRO.hostname, customDomain); + t.is(registerDomainResponseRO.companyId, companyId); + t.is(Object.hasOwn(registerDomainResponseRO, 'id'), true); + t.is(Object.hasOwn(registerDomainResponseRO, 'createdAt'), true); + t.is(Object.keys(registerDomainResponseRO).length, 5); + + const deleteDomainResponse = await sendRequestToSaasPart( + `custom-domain/delete/${companyId}`, + 'DELETE', + undefined, + adminUserToken, + ); + t.is(deleteDomainResponse.status, 200); + const deleteDomainResponseRO = await deleteDomainResponse.json(); + t.is(deleteDomainResponseRO.success, true); + + // check that domain was deleted + + const foundDomainResponse = await sendRequestToSaasPart( + `custom-domain/${companyId}`, + 'GET', + undefined, + adminUserToken, + ); + + const foundDomainResponseRO = await foundDomainResponse.json(); + t.is(Object.hasOwn(foundDomainResponseRO, 'success'), true); + t.is(foundDomainResponseRO.success, false); + t.is(Object.hasOwn(foundDomainResponseRO, 'domain_info'), true); + t.is(foundDomainResponseRO.domain_info, null); + } catch (error) { + t.fail(error.message); + } }); diff --git a/backend/test/ava-tests/saas-tests/custom-field-e2e.test.ts b/backend/test/ava-tests/saas-tests/custom-field-e2e.test.ts index 9f608291b..c192bee09 100644 --- a/backend/test/ava-tests/saas-tests/custom-field-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/custom-field-e2e.test.ts @@ -29,1718 +29,1718 @@ const mockFactory = new MockFactory(); const masterPwd = 'ahalaimahalai'; const _decryptValue = (data) => { - return Encryptor.decryptData(data); + return Encryptor.decryptData(data); }; const _decryptValueMaterPwd = (data) => { - return Encryptor.decryptDataMasterPwd(data, masterPwd); + return Encryptor.decryptDataMasterPwd(data, masterPwd); }; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); let currentTest = 'GET /fields/:slug'; test.serial(`${currentTest} should return empty array, when custom fields not created`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - t.is(getCustomFields.status, 200); - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 0); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + t.is(getCustomFields.status, 200); + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 0); }); test.serial(`${currentTest} should return custom fields array, when custom fields are created`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(getTableRowsRO.rows.length > 0, true); - for (const row of getTableRowsRO.rows) { - t.is(Object.hasOwn(row, '#autoadmin:customFields'), true); - t.is(typeof row['#autoadmin:customFields'], 'object'); - t.is(row['#autoadmin:customFields'].length, 1); - t.is(row['#autoadmin:customFields'][0].type, newCustomField.type); - t.is(row['#autoadmin:customFields'][0].text, newCustomField.text); - const urlTemplate = replaceTextInCurlies(newCustomField.template_string, ['id', 'title'], [row.id, row.title]); - t.is(row['#autoadmin:customFields'][0].url_template, urlTemplate); - } + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(getTableRowsRO.rows.length > 0, true); + for (const row of getTableRowsRO.rows) { + t.is(Object.hasOwn(row, '#autoadmin:customFields'), true); + t.is(typeof row['#autoadmin:customFields'], 'object'); + t.is(row['#autoadmin:customFields'].length, 1); + t.is(row['#autoadmin:customFields'][0].type, newCustomField.type); + t.is(row['#autoadmin:customFields'][0].text, newCustomField.text); + const urlTemplate = replaceTextInCurlies(newCustomField.template_string, ['id', 'title'], [row.id, row.title]); + t.is(row['#autoadmin:customFields'][0].url_template, urlTemplate); + } }); test.serial(`${currentTest} should throw exception when connection id not passed in request`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - - t.is(createCustomFieldResponse.status, 201); - - createConnectionRO.id = ''; - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 404); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + + t.is(createCustomFieldResponse.status, 201); + + createConnectionRO.id = ''; + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 404); }); test.serial(`${currentTest} should throw exception when connection id passed in request is incorrect`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - - createConnectionRO.id = faker.string.uuid(); - - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - - t.is(createCustomFieldResponse.status, 403); - t.is(createCustomField.message, Messages.DONT_HAVE_PERMISSIONS); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + + createConnectionRO.id = faker.string.uuid(); + + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + + t.is(createCustomFieldResponse.status, 403); + t.is(createCustomField.message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw exception when tableName passed in request is incorrect`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const tableName = faker.lorem.words(2); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=${tableName}`) - .send(newCustomField) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - - t.is(createCustomFieldResponse.status, 400); - t.is(createCustomField.message, Messages.TABLE_NOT_FOUND); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const tableName = faker.lorem.words(2); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=${tableName}`) + .send(newCustomField) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + + t.is(createCustomFieldResponse.status, 400); + t.is(createCustomField.message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw exception when tableName not passed in request`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=`) - .send(newCustomField) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - - t.is(createCustomFieldResponse.status, 400); - t.is(createCustomField.message, Messages.TABLE_NAME_MISSING); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=`) + .send(newCustomField) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + + t.is(createCustomFieldResponse.status, 400); + t.is(createCustomField.message, Messages.TABLE_NAME_MISSING); }); currentTest = 'POST /fields/:slug'; test.serial(`${currentTest} should return table settings with created custom field`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); }); test.serial( - `${currentTest} should throw exception when custom field without text field passed in request`, - async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - delete newCustomField.text; - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const _createCustomField = JSON.parse(createCustomFieldResponse.text); - - t.is(createCustomFieldResponse.status, 400); - // t.is(createCustomField.message, ErrorsMessages.VALIDATION_FAILED); - }, + `${currentTest} should throw exception when custom field without text field passed in request`, + async (t) => { + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + delete newCustomField.text; + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const _createCustomField = JSON.parse(createCustomFieldResponse.text); + + t.is(createCustomFieldResponse.status, 400); + // t.is(createCustomField.message, ErrorsMessages.VALIDATION_FAILED); + }, ); test.serial( - `${currentTest} should throw exception when custom field without type field passed in request`, - async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - delete newCustomField.type; - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const _createCustomField = JSON.parse(createCustomFieldResponse.text); - - t.is(createCustomFieldResponse.status, 400); - // t.is(createCustomField.message, ErrorsMessages.VALIDATION_FAILED); - }, + `${currentTest} should throw exception when custom field without type field passed in request`, + async (t) => { + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + delete newCustomField.type; + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const _createCustomField = JSON.parse(createCustomFieldResponse.text); + + t.is(createCustomFieldResponse.status, 400); + // t.is(createCustomField.message, ErrorsMessages.VALIDATION_FAILED); + }, ); test.serial( - `${currentTest} should throw exception when custom field without template_string field passed in request`, - async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - delete newCustomField.template_string; - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - - const _createCustomField = JSON.parse(createCustomFieldResponse.text); - - t.is(createCustomFieldResponse.status, 400); - // t.is(createCustomField.message, ErrorsMessages.VALIDATION_FAILED); - }, + `${currentTest} should throw exception when custom field without template_string field passed in request`, + async (t) => { + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + delete newCustomField.template_string; + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + + const _createCustomField = JSON.parse(createCustomFieldResponse.text); + + t.is(createCustomFieldResponse.status, 400); + // t.is(createCustomField.message, ErrorsMessages.VALIDATION_FAILED); + }, ); test.serial( - `${currentTest} should throw exception when custom field with incorrect type passed in request`, - async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - newCustomField.type = 'test'; - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - - t.is(createCustomFieldResponse.status, 400); - t.is(createCustomField.message, Messages.CUSTOM_FIELD_TYPE_INCORRECT); - }, + `${currentTest} should throw exception when custom field with incorrect type passed in request`, + async (t) => { + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + newCustomField.type = 'test'; + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + + t.is(createCustomFieldResponse.status, 400); + t.is(createCustomField.message, Messages.CUSTOM_FIELD_TYPE_INCORRECT); + }, ); test.serial( - `${currentTest} should throw complex exception when custom field with incorrect type and without text property passed in request`, - async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - newCustomField.type = 'test'; - delete newCustomField.text; - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const _createCustomField = JSON.parse(createCustomFieldResponse.text); - - t.is(createCustomFieldResponse.status, 400); - // t.is(createCustomField.message, ErrorsMessages.VALIDATION_FAILED); - }, + `${currentTest} should throw complex exception when custom field with incorrect type and without text property passed in request`, + async (t) => { + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + newCustomField.type = 'test'; + delete newCustomField.text; + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const _createCustomField = JSON.parse(createCustomFieldResponse.text); + + t.is(createCustomFieldResponse.status, 400); + // t.is(createCustomField.message, ErrorsMessages.VALIDATION_FAILED); + }, ); test.serial(`${currentTest} should throw exception when connection id not passed in request`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - createConnectionRO.id = ''; - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(createCustomFieldResponse.status, 404); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + createConnectionRO.id = ''; + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(createCustomFieldResponse.status, 404); }); test.serial(`${currentTest} should throw exception when connection id passed in request is incorrect`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - createConnectionRO.id = faker.string.uuid(); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - - t.is(createCustomFieldResponse.status, 403); - t.is(createCustomField.message, Messages.DONT_HAVE_PERMISSIONS); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + createConnectionRO.id = faker.string.uuid(); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + + t.is(createCustomFieldResponse.status, 403); + t.is(createCustomField.message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw exception when tableName passed in request is incorrect`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const tableName = faker.lorem.words(2); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=${tableName}`) - .send(newCustomField) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - - t.is(createCustomFieldResponse.status, 400); - t.is(createCustomField.message, Messages.TABLE_NOT_FOUND); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const tableName = faker.lorem.words(2); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=${tableName}`) + .send(newCustomField) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + + t.is(createCustomFieldResponse.status, 400); + t.is(createCustomField.message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw exception when tableName not passed in request`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=`) - .send(newCustomField) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - - t.is(createCustomFieldResponse.status, 400); - t.is(createCustomField.message, Messages.TABLE_NAME_MISSING); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=`) + .send(newCustomField) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + + t.is(createCustomFieldResponse.status, 400); + t.is(createCustomField.message, Messages.TABLE_NAME_MISSING); }); currentTest = 'PUT /fields/:slug'; test.serial(`${currentTest} should return updated custom field`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - const updateDTO = { - id: getCustomFieldsRO[0].id, - type: getCustomFieldsRO[0].type, - text: 'updated', - template_string: 'https//?connectionId={{id}}&connectionType={{type}}', - }; - const updateCustomFieldResponse = await request(app.getHttpServer()) - .put(`/field/${createConnectionRO.id}?tableName=connection`) - .send(updateDTO) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(updateCustomFieldResponse.status, 200); - const updateCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); - - t.is(updateCustomFieldRO.type, updateDTO.type); - t.is(updateCustomFieldRO.template_string, updateDTO.template_string); - t.is(updateCustomFieldRO.text, updateDTO.text); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + const updateDTO = { + id: getCustomFieldsRO[0].id, + type: getCustomFieldsRO[0].type, + text: 'updated', + template_string: 'https//?connectionId={{id}}&connectionType={{type}}', + }; + const updateCustomFieldResponse = await request(app.getHttpServer()) + .put(`/field/${createConnectionRO.id}?tableName=connection`) + .send(updateDTO) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(updateCustomFieldResponse.status, 200); + const updateCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); + + t.is(updateCustomFieldRO.type, updateDTO.type); + t.is(updateCustomFieldRO.template_string, updateDTO.template_string); + t.is(updateCustomFieldRO.text, updateDTO.text); }); test.serial(`${currentTest} should throw exception, when connection id not passed in request`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - const updateDTO = { - id: getCustomFieldsRO[0].id, - type: getCustomFieldsRO[0].type, - text: 'updated', - template_string: 'https//?connectionId={{id}}&connectionType={{type}}', - }; - createConnectionRO.id = ''; - const updateCustomFieldResponse = await request(app.getHttpServer()) - .put(`/field/${createConnectionRO.id}?tableName=connection`) - .send(updateDTO) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(updateCustomFieldResponse.status, 404); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + const updateDTO = { + id: getCustomFieldsRO[0].id, + type: getCustomFieldsRO[0].type, + text: 'updated', + template_string: 'https//?connectionId={{id}}&connectionType={{type}}', + }; + createConnectionRO.id = ''; + const updateCustomFieldResponse = await request(app.getHttpServer()) + .put(`/field/${createConnectionRO.id}?tableName=connection`) + .send(updateDTO) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(updateCustomFieldResponse.status, 404); }); test.serial(`${currentTest} should throw exception, when connection id passed in request is incorrect`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - const updateDTO = { - id: getCustomFieldsRO[0].id, - type: getCustomFieldsRO[0].type, - text: 'updated', - template_string: 'https//?connectionId={{id}}&connectionType={{type}}', - }; - createConnectionRO.id = faker.string.uuid(); - const updateCustomFieldResponse = await request(app.getHttpServer()) - .put(`/field/${createConnectionRO.id}?tableName=connection`) - .send(updateDTO) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - - const updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); - t.is(updateCustomFieldResponse.status, 403); - t.is(updatedCustomFieldRO.message, Messages.DONT_HAVE_PERMISSIONS); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + const updateDTO = { + id: getCustomFieldsRO[0].id, + type: getCustomFieldsRO[0].type, + text: 'updated', + template_string: 'https//?connectionId={{id}}&connectionType={{type}}', + }; + createConnectionRO.id = faker.string.uuid(); + const updateCustomFieldResponse = await request(app.getHttpServer()) + .put(`/field/${createConnectionRO.id}?tableName=connection`) + .send(updateDTO) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + + const updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); + t.is(updateCustomFieldResponse.status, 403); + t.is(updatedCustomFieldRO.message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw exception, when tableName passed in request is incorrect`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - const updateDTO = { - id: getCustomFieldsRO[0].id, - type: getCustomFieldsRO[0].type, - text: 'updated', - template_string: 'https//?connectionId={{id}}&connectionType={{type}}', - }; - const tableName = faker.lorem.words(); - const updateCustomFieldResponse = await request(app.getHttpServer()) - .put(`/field/${createConnectionRO.id}?tableName=${tableName}`) - .send(updateDTO) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - - const updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); - t.is(updateCustomFieldResponse.status, 400); - t.is(updatedCustomFieldRO.message, Messages.TABLE_NOT_FOUND); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + const updateDTO = { + id: getCustomFieldsRO[0].id, + type: getCustomFieldsRO[0].type, + text: 'updated', + template_string: 'https//?connectionId={{id}}&connectionType={{type}}', + }; + const tableName = faker.lorem.words(); + const updateCustomFieldResponse = await request(app.getHttpServer()) + .put(`/field/${createConnectionRO.id}?tableName=${tableName}`) + .send(updateDTO) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + + const updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); + t.is(updateCustomFieldResponse.status, 400); + t.is(updatedCustomFieldRO.message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw exception, when tableName not passed in request`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - const updateDTO = { - id: getCustomFieldsRO[0].id, - type: getCustomFieldsRO[0].type, - text: 'updated', - template_string: 'https//?connectionId={{id}}&connectionType={{type}}', - }; - const tableName = ''; - const updateCustomFieldResponse = await request(app.getHttpServer()) - .put(`/field/${createConnectionRO.id}?tableName=${tableName}`) - .send(updateDTO) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - - const updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); - t.is(updateCustomFieldResponse.status, 400); - t.is(updatedCustomFieldRO.message, Messages.TABLE_NAME_MISSING); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + const updateDTO = { + id: getCustomFieldsRO[0].id, + type: getCustomFieldsRO[0].type, + text: 'updated', + template_string: 'https//?connectionId={{id}}&connectionType={{type}}', + }; + const tableName = ''; + const updateCustomFieldResponse = await request(app.getHttpServer()) + .put(`/field/${createConnectionRO.id}?tableName=${tableName}`) + .send(updateDTO) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + + const updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); + t.is(updateCustomFieldResponse.status, 400); + t.is(updatedCustomFieldRO.message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw exception, when field id not passed in request`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - const updateDTO = { - id: undefined, - type: getCustomFieldsRO[0].type, - text: 'updated', - template_string: 'https//?connectionId={{id}}&connectionType={{type}}', - }; - const updateCustomFieldResponse = await request(app.getHttpServer()) - .put(`/field/${createConnectionRO.id}?tableName=connection`) - .send(updateDTO) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - - const _updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); - t.is(updateCustomFieldResponse.status, 400); - // t.is(updatedCustomFieldRO.message, ErrorsMessages.VALIDATION_FAILED); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + const updateDTO = { + id: undefined, + type: getCustomFieldsRO[0].type, + text: 'updated', + template_string: 'https//?connectionId={{id}}&connectionType={{type}}', + }; + const updateCustomFieldResponse = await request(app.getHttpServer()) + .put(`/field/${createConnectionRO.id}?tableName=connection`) + .send(updateDTO) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + + const _updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); + t.is(updateCustomFieldResponse.status, 400); + // t.is(updatedCustomFieldRO.message, ErrorsMessages.VALIDATION_FAILED); }); test.serial(`${currentTest} should throw exception, when field type not passed in request`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - const updateDTO = { - id: getCustomFieldsRO[0].id, - type: undefined, - text: 'updated', - template_string: 'https//?connectionId={{id}}&connectionType={{type}}', - }; - const updateCustomFieldResponse = await request(app.getHttpServer()) - .put(`/field/${createConnectionRO.id}?tableName=connection`) - .send(updateDTO) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - - const _updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); - t.is(updateCustomFieldResponse.status, 400); - // t.is(updatedCustomFieldRO.message, ErrorsMessages.VALIDATION_FAILED); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + const updateDTO = { + id: getCustomFieldsRO[0].id, + type: undefined, + text: 'updated', + template_string: 'https//?connectionId={{id}}&connectionType={{type}}', + }; + const updateCustomFieldResponse = await request(app.getHttpServer()) + .put(`/field/${createConnectionRO.id}?tableName=connection`) + .send(updateDTO) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + + const _updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); + t.is(updateCustomFieldResponse.status, 400); + // t.is(updatedCustomFieldRO.message, ErrorsMessages.VALIDATION_FAILED); }); test.serial(`${currentTest} should throw exception, when field type passed in request is incorrect`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - const updateDTO = { - id: getCustomFieldsRO[0].id, - type: faker.lorem.words(), - text: 'updated', - template_string: 'https//?connectionId={{id}}&connectionType={{type}}', - }; - const updateCustomFieldResponse = await request(app.getHttpServer()) - .put(`/field/${createConnectionRO.id}?tableName=connection`) - .send(updateDTO) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - - const updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); - t.is(updateCustomFieldResponse.status, 400); - t.is(updatedCustomFieldRO.message, Messages.CUSTOM_FIELD_TYPE_INCORRECT); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + const updateDTO = { + id: getCustomFieldsRO[0].id, + type: faker.lorem.words(), + text: 'updated', + template_string: 'https//?connectionId={{id}}&connectionType={{type}}', + }; + const updateCustomFieldResponse = await request(app.getHttpServer()) + .put(`/field/${createConnectionRO.id}?tableName=connection`) + .send(updateDTO) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + + const updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); + t.is(updateCustomFieldResponse.status, 400); + t.is(updatedCustomFieldRO.message, Messages.CUSTOM_FIELD_TYPE_INCORRECT); }); test.serial(`${currentTest} should throw exception, when field text is not passed in request`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - const updateDTO = { - id: getCustomFieldsRO[0].id, - type: getCustomFieldsRO[0].type, - text: undefined, - template_string: 'https//?connectionId={{id}}&connectionType={{type}}', - }; - const updateCustomFieldResponse = await request(app.getHttpServer()) - .put(`/field/${createConnectionRO.id}?tableName=connection`) - .send(updateDTO) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - - const _updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); - t.is(updateCustomFieldResponse.status, 400); - // t.is(updatedCustomFieldRO.message, ErrorsMessages.VALIDATION_FAILED); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + const updateDTO = { + id: getCustomFieldsRO[0].id, + type: getCustomFieldsRO[0].type, + text: undefined, + template_string: 'https//?connectionId={{id}}&connectionType={{type}}', + }; + const updateCustomFieldResponse = await request(app.getHttpServer()) + .put(`/field/${createConnectionRO.id}?tableName=connection`) + .send(updateDTO) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + + const _updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); + t.is(updateCustomFieldResponse.status, 400); + // t.is(updatedCustomFieldRO.message, ErrorsMessages.VALIDATION_FAILED); }); test.serial(`${currentTest} should throw exception, when field template_string is not passed in request`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - const updateDTO = { - id: getCustomFieldsRO[0].id, - type: getCustomFieldsRO[0].type, - text: 'updated', - template_string: undefined, - }; - const updateCustomFieldResponse = await request(app.getHttpServer()) - .put(`/field/${createConnectionRO.id}?tableName=connection`) - .send(updateDTO) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - - const _updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); - t.is(updateCustomFieldResponse.status, 400); - // t.is(updatedCustomFieldRO.message, ErrorsMessages.VALIDATION_FAILED); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + const updateDTO = { + id: getCustomFieldsRO[0].id, + type: getCustomFieldsRO[0].type, + text: 'updated', + template_string: undefined, + }; + const updateCustomFieldResponse = await request(app.getHttpServer()) + .put(`/field/${createConnectionRO.id}?tableName=connection`) + .send(updateDTO) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + + const _updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); + t.is(updateCustomFieldResponse.status, 400); + // t.is(updatedCustomFieldRO.message, ErrorsMessages.VALIDATION_FAILED); }); test.serial(`${currentTest} should throw exception, when fields passed in template string are incorrect`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - const randomField1 = faker.lorem.words(1); - const randomField2 = faker.lorem.words(1); - const updateDTO = { - id: getCustomFieldsRO[0].id, - type: getCustomFieldsRO[0].type, - text: 'updated', - template_string: `https//?connectionId={{${randomField1}}}&connectionType={{${randomField2}}}`, - }; - const updateCustomFieldResponse = await request(app.getHttpServer()) - .put(`/field/${createConnectionRO.id}?tableName=connection`) - .send(updateDTO) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - - const updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); - t.is(updateCustomFieldResponse.status, 400); - t.is( - updatedCustomFieldRO.message, - `${Messages.EXCLUDED_OR_NOT_EXISTS(randomField1)}, ${Messages.EXCLUDED_OR_NOT_EXISTS(randomField2)}`, - ); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + const randomField1 = faker.lorem.words(1); + const randomField2 = faker.lorem.words(1); + const updateDTO = { + id: getCustomFieldsRO[0].id, + type: getCustomFieldsRO[0].type, + text: 'updated', + template_string: `https//?connectionId={{${randomField1}}}&connectionType={{${randomField2}}}`, + }; + const updateCustomFieldResponse = await request(app.getHttpServer()) + .put(`/field/${createConnectionRO.id}?tableName=connection`) + .send(updateDTO) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + + const updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); + t.is(updateCustomFieldResponse.status, 400); + t.is( + updatedCustomFieldRO.message, + `${Messages.EXCLUDED_OR_NOT_EXISTS(randomField1)}, ${Messages.EXCLUDED_OR_NOT_EXISTS(randomField2)}`, + ); }); test.serial( - `${currentTest} should throw complex exception, when some required fields not passed in request`, - async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - const updateDTO = { - id: getCustomFieldsRO[0].id, - type: undefined, - text: 'updated', - template_string: undefined, - }; - const updateCustomFieldResponse = await request(app.getHttpServer()) - .put(`/field/${createConnectionRO.id}?tableName=connection`) - .send(updateDTO) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - - const _updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); - t.is(updateCustomFieldResponse.status, 400); - // t.is(updatedCustomFieldRO.message, ErrorsMessages.VALIDATION_FAILED); - }, + `${currentTest} should throw complex exception, when some required fields not passed in request`, + async (t) => { + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + const updateDTO = { + id: getCustomFieldsRO[0].id, + type: undefined, + text: 'updated', + template_string: undefined, + }; + const updateCustomFieldResponse = await request(app.getHttpServer()) + .put(`/field/${createConnectionRO.id}?tableName=connection`) + .send(updateDTO) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + + const _updatedCustomFieldRO = JSON.parse(updateCustomFieldResponse.text); + t.is(updateCustomFieldResponse.status, 400); + // t.is(updatedCustomFieldRO.message, ErrorsMessages.VALIDATION_FAILED); + }, ); currentTest = 'DELETE /fields/:slug'; test.serial(`${currentTest} should return table settings without deleted custom field`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - let getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - let getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - const deleteCustomField = await request(app.getHttpServer()) - .delete(`/field/${createConnectionRO.id}?tableName=connection&id=${getCustomFieldsRO[0].id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(deleteCustomField.status, 200); - const deleteCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(deleteCustomFieldsRO.length, 1); - - t.is(deleteCustomFieldsRO[0].type, newCustomField.type); - t.is(deleteCustomFieldsRO[0].text, newCustomField.text); - t.is(deleteCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 0); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + let getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + let getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + const deleteCustomField = await request(app.getHttpServer()) + .delete(`/field/${createConnectionRO.id}?tableName=connection&id=${getCustomFieldsRO[0].id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(deleteCustomField.status, 200); + const deleteCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(deleteCustomFieldsRO.length, 1); + + t.is(deleteCustomFieldsRO[0].type, newCustomField.type); + t.is(deleteCustomFieldsRO[0].text, newCustomField.text); + t.is(deleteCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 0); }); test.serial(`${currentTest} should throw exception, when connection id not passed in request`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - createConnectionRO.id = ''; - const deleteCustomField = await request(app.getHttpServer()) - .delete(`/field/${createConnectionRO.id}?tableName=connection&id=${getCustomFieldsRO[0].id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(deleteCustomField.status, 404); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + createConnectionRO.id = ''; + const deleteCustomField = await request(app.getHttpServer()) + .delete(`/field/${createConnectionRO.id}?tableName=connection&id=${getCustomFieldsRO[0].id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(deleteCustomField.status, 404); }); test.serial(`${currentTest} should throw exception, when connection id passed in request is incorrect`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - createConnectionRO.id = faker.string.uuid(); - const deleteCustomField = await request(app.getHttpServer()) - .delete(`/field/${createConnectionRO.id}?tableName=connection&id=${getCustomFieldsRO[0].id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(deleteCustomField.status, 403); - const deleteCustomFieldsRO = JSON.parse(deleteCustomField.text); - t.is(deleteCustomFieldsRO.message, Messages.DONT_HAVE_PERMISSIONS); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + createConnectionRO.id = faker.string.uuid(); + const deleteCustomField = await request(app.getHttpServer()) + .delete(`/field/${createConnectionRO.id}?tableName=connection&id=${getCustomFieldsRO[0].id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(deleteCustomField.status, 403); + const deleteCustomFieldsRO = JSON.parse(deleteCustomField.text); + t.is(deleteCustomFieldsRO.message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw exception, when tableName not passed in request`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - const deleteCustomField = await request(app.getHttpServer()) - .delete(`/field/${createConnectionRO.id}?tableName=&id=${getCustomFieldsRO[0].id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(deleteCustomField.status, 400); - const deleteCustomFieldsRO = JSON.parse(deleteCustomField.text); - t.is(deleteCustomFieldsRO.message, Messages.TABLE_NAME_MISSING); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + const deleteCustomField = await request(app.getHttpServer()) + .delete(`/field/${createConnectionRO.id}?tableName=&id=${getCustomFieldsRO[0].id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(deleteCustomField.status, 400); + const deleteCustomFieldsRO = JSON.parse(deleteCustomField.text); + t.is(deleteCustomFieldsRO.message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw exception, when tableName passed in request is incorrect`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - const tableName = faker.lorem.words(); - const deleteCustomField = await request(app.getHttpServer()) - .delete(`/field/${createConnectionRO.id}?tableName=${tableName}&id=${getCustomFieldsRO[0].id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(deleteCustomField.status, 400); - const deleteCustomFieldsRO = JSON.parse(deleteCustomField.text); - t.is(deleteCustomFieldsRO.message, Messages.TABLE_SETTINGS_NOT_FOUND); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + const tableName = faker.lorem.words(); + const deleteCustomField = await request(app.getHttpServer()) + .delete(`/field/${createConnectionRO.id}?tableName=${tableName}&id=${getCustomFieldsRO[0].id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(deleteCustomField.status, 400); + const deleteCustomFieldsRO = JSON.parse(deleteCustomField.text); + t.is(deleteCustomFieldsRO.message, Messages.TABLE_SETTINGS_NOT_FOUND); }); test.serial(`${currentTest} should throw exception, when field id is not passed in request`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - getCustomFieldsRO[0].id = ''; - const deleteCustomField = await request(app.getHttpServer()) - .delete(`/field/${createConnectionRO.id}?tableName=connection&id=${getCustomFieldsRO[0].id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(deleteCustomField.status, 400); - const deleteCustomFieldsRO = JSON.parse(deleteCustomField.text); - t.is(deleteCustomFieldsRO.message, Messages.UUID_INVALID); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + getCustomFieldsRO[0].id = ''; + const deleteCustomField = await request(app.getHttpServer()) + .delete(`/field/${createConnectionRO.id}?tableName=connection&id=${getCustomFieldsRO[0].id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(deleteCustomField.status, 400); + const deleteCustomFieldsRO = JSON.parse(deleteCustomField.text); + t.is(deleteCustomFieldsRO.message, Messages.UUID_INVALID); }); test.serial(`${currentTest} should throw exception, when field id passed in request is incorrect`, async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newEncryptedConnection) - .set('masterpwd', 'ahalaimahalai') - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); - const createCustomFieldResponse = await request(app.getHttpServer()) - .post(`/field/${createConnectionRO.id}?tableName=connection`) - .send(newCustomField) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - const createCustomField = JSON.parse(createCustomFieldResponse.text); - t.is(createCustomFieldResponse.status, 201); - t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); - t.is(typeof createCustomField.custom_fields, 'object'); - - const getCustomFields = await request(app.getHttpServer()) - .get(`/fields/${createConnectionRO.id}?tableName=connection`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(getCustomFields.status, 200); - const getCustomFieldsRO = JSON.parse(getCustomFields.text); - - t.is(typeof getCustomFieldsRO, 'object'); - t.is(getCustomFieldsRO.length, 1); - - t.is(getCustomFieldsRO[0].type, newCustomField.type); - t.is(getCustomFieldsRO[0].text, newCustomField.text); - t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); - - getCustomFieldsRO[0].id = faker.string.uuid(); - const deleteCustomField = await request(app.getHttpServer()) - .delete(`/field/${createConnectionRO.id}?tableName=connection&id=${getCustomFieldsRO[0].id}`) - .set('Content-Type', 'application/json') - .set('Cookie', token) - .set('masterpwd', 'ahalaimahalai') - .set('Accept', 'application/json'); - t.is(deleteCustomField.status, 400); - const deleteCustomFieldsRO = JSON.parse(deleteCustomField.text); - t.is(deleteCustomFieldsRO.message, Messages.CUSTOM_FIELD_NOT_FOUND); + const { token } = await registerUserAndReturnUserInfo(app); + const { newEncryptedConnection, newEncryptedConnection2 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newEncryptedConnection) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const newCustomField = mockFactory.generateCustomFieldForConnectionTable('id', 'title'); + const createCustomFieldResponse = await request(app.getHttpServer()) + .post(`/field/${createConnectionRO.id}?tableName=connection`) + .send(newCustomField) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createCustomField = JSON.parse(createCustomFieldResponse.text); + t.is(createCustomFieldResponse.status, 201); + t.is(Object.hasOwn(createCustomField, 'custom_fields'), true); + t.is(typeof createCustomField.custom_fields, 'object'); + + const getCustomFields = await request(app.getHttpServer()) + .get(`/fields/${createConnectionRO.id}?tableName=connection`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getCustomFields.status, 200); + const getCustomFieldsRO = JSON.parse(getCustomFields.text); + + t.is(typeof getCustomFieldsRO, 'object'); + t.is(getCustomFieldsRO.length, 1); + + t.is(getCustomFieldsRO[0].type, newCustomField.type); + t.is(getCustomFieldsRO[0].text, newCustomField.text); + t.is(getCustomFieldsRO[0].template_string, 'https//?connectionId={{id}}&connectionTitle={{title}}'); + + getCustomFieldsRO[0].id = faker.string.uuid(); + const deleteCustomField = await request(app.getHttpServer()) + .delete(`/field/${createConnectionRO.id}?tableName=connection&id=${getCustomFieldsRO[0].id}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(deleteCustomField.status, 400); + const deleteCustomFieldsRO = JSON.parse(deleteCustomField.text); + t.is(deleteCustomFieldsRO.message, Messages.CUSTOM_FIELD_NOT_FOUND); }); diff --git a/backend/test/ava-tests/saas-tests/different-tables-structures-e2e-test.ts b/backend/test/ava-tests/saas-tests/different-tables-structures-e2e-test.ts index b3225c75e..63b5926c3 100644 --- a/backend/test/ava-tests/saas-tests/different-tables-structures-e2e-test.ts +++ b/backend/test/ava-tests/saas-tests/different-tables-structures-e2e-test.ts @@ -35,34 +35,34 @@ const _testTables: Array = []; let currentTest; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication() as any; - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); - await loadTestData(); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication() as any; + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); + await loadTestData(); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); const testUsersTableName = 'users'; @@ -92,151 +92,151 @@ const createTransactionsTableRawQuery = `CREATE TABLE transactions ( const testEntitiesCount = 500; async function fillUsersTable(knex: Knex): Promise { - for (let i = 0; i < testEntitiesCount; i++) { - await knex('users').insert({ username: faker.person.firstName() }); - } + for (let i = 0; i < testEntitiesCount; i++) { + await knex('users').insert({ username: faker.person.firstName() }); + } } const insertedIdCombos: Array<{ buyerid: number; reviewerid: number }> = []; async function fillTransactionsTable(knex: Knex): Promise { - for (let i = 0; i < testEntitiesCount; i++) { - const { buyerid, reviewerid } = getUniqueIdsComboForInsert(); - await knex('transactions').insert({ - buyerid: buyerid, - reviewerid: reviewerid, - transaction_date: faker.date.past(), - description: faker.lorem.sentence(), - amount: faker.number.int({ min: 100, max: 10000 }), - }); - } + for (let i = 0; i < testEntitiesCount; i++) { + const { buyerid, reviewerid } = getUniqueIdsComboForInsert(); + await knex('transactions').insert({ + buyerid: buyerid, + reviewerid: reviewerid, + transaction_date: faker.date.past(), + description: faker.lorem.sentence(), + amount: faker.number.int({ min: 100, max: 10000 }), + }); + } } function getUniqueIdsCombo(): { buyerid: number; reviewerid: number } { - return { - buyerid: faker.number.int({ min: 1, max: testEntitiesCount }), - reviewerid: faker.number.int({ min: 1, max: testEntitiesCount }), - }; + return { + buyerid: faker.number.int({ min: 1, max: testEntitiesCount }), + reviewerid: faker.number.int({ min: 1, max: testEntitiesCount }), + }; } function getUniqueIdsComboForInsert(): { buyerid: number; reviewerid: number } { - if (insertedIdCombos.length >= testEntitiesCount) { - return insertedIdCombos.shift(); - } - while (true) { - const { buyerid, reviewerid } = getUniqueIdsCombo(); - if (!insertedIdCombos.find((idCombo) => idCombo.buyerid === buyerid && idCombo.reviewerid === reviewerid)) { - insertedIdCombos.push({ buyerid, reviewerid }); - return { buyerid, reviewerid }; - } - } + if (insertedIdCombos.length >= testEntitiesCount) { + return insertedIdCombos.shift(); + } + while (true) { + const { buyerid, reviewerid } = getUniqueIdsCombo(); + if (!insertedIdCombos.find((idCombo) => idCombo.buyerid === buyerid && idCombo.reviewerid === reviewerid)) { + insertedIdCombos.push({ buyerid, reviewerid }); + return { buyerid, reviewerid }; + } + } } async function loadTestData(): Promise { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; - const testKnex = getTestKnex(connectionToTestDB); - await testKnex.raw(`DROP TABLE IF EXISTS transactions;`); - await testKnex.raw(`DROP TABLE IF EXISTS users;`); - await testKnex.raw(createUsersTableRawQuery); - await testKnex.raw(createTransactionsTableRawQuery); - await fillUsersTable(testKnex); - await fillTransactionsTable(testKnex); - await clearAllTestKnex(); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; + const testKnex = getTestKnex(connectionToTestDB); + await testKnex.raw(`DROP TABLE IF EXISTS transactions;`); + await testKnex.raw(`DROP TABLE IF EXISTS users;`); + await testKnex.raw(createUsersTableRawQuery); + await testKnex.raw(createTransactionsTableRawQuery); + await fillUsersTable(testKnex); + await fillTransactionsTable(testKnex); + await clearAllTestKnex(); } currentTest = 'GET /connection/tables/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTablesRO = JSON.parse(getTablesResponse.text); - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.length > 0, true); - } catch (error) { - console.error(error); - throw error; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTablesRO = JSON.parse(getTablesResponse.text); + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.length > 0, true); + } catch (error) { + console.error(error); + throw error; + } }); currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return list of rows of the tables`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const foundRowsFromUsersTableResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testUsersTableName}&page=1&perPage=500`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const foundRowsFromUsersTableRO = JSON.parse(foundRowsFromUsersTableResponse.text); - t.is(typeof foundRowsFromUsersTableRO, 'object'); - t.is(Object.hasOwn(foundRowsFromUsersTableRO, 'rows'), true); - t.is(Object.hasOwn(foundRowsFromUsersTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(foundRowsFromUsersTableRO, 'pagination'), true); - t.is(foundRowsFromUsersTableRO.rows.length, 500); - t.is(Object.keys(foundRowsFromUsersTableRO.rows[1]).length, 4); - t.is(Object.hasOwn(foundRowsFromUsersTableRO.rows[0], 'userid'), true); - t.is(Object.hasOwn(foundRowsFromUsersTableRO.rows[1], 'username'), true); - t.is(Object.hasOwn(foundRowsFromUsersTableRO.rows[2], 'created_at'), true); - - const foundRowsFromTransactionsTableResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTransactionsTableName}&page=1&perPage=500`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const foundRowsFromTransactionsTableRO = JSON.parse(foundRowsFromTransactionsTableResponse.text); - t.is(typeof foundRowsFromTransactionsTableRO, 'object'); - t.is(Object.hasOwn(foundRowsFromTransactionsTableRO, 'rows'), true); - t.is(Object.hasOwn(foundRowsFromTransactionsTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(foundRowsFromTransactionsTableRO, 'pagination'), true); - t.is(foundRowsFromTransactionsTableRO.rows.length, 500); - t.is(Object.keys(foundRowsFromTransactionsTableRO.rows[1]).length, 7); - t.is(Object.hasOwn(foundRowsFromTransactionsTableRO.rows[0], 'buyerid'), true); - t.is(Object.hasOwn(foundRowsFromTransactionsTableRO.rows[1], 'reviewerid'), true); - t.is(Object.hasOwn(foundRowsFromTransactionsTableRO.rows[2], 'transaction_date'), true); - - for (const row of foundRowsFromTransactionsTableRO.rows) { - t.is(Object.hasOwn(row, 'buyerid'), true); - const buyerId = row.buyerid; - t.is(typeof buyerId, 'object'); - t.is(Object.hasOwn(buyerId, 'userid'), true); - t.is(typeof buyerId.userid, 'number'); - const reviewerId = row.reviewerid; - t.is(typeof reviewerId, 'object'); - t.is(Object.hasOwn(reviewerId, 'userid'), true); - t.is(typeof reviewerId.userid, 'number'); - } - } catch (error) { - console.error(error); - throw error; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const foundRowsFromUsersTableResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testUsersTableName}&page=1&perPage=500`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const foundRowsFromUsersTableRO = JSON.parse(foundRowsFromUsersTableResponse.text); + t.is(typeof foundRowsFromUsersTableRO, 'object'); + t.is(Object.hasOwn(foundRowsFromUsersTableRO, 'rows'), true); + t.is(Object.hasOwn(foundRowsFromUsersTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(foundRowsFromUsersTableRO, 'pagination'), true); + t.is(foundRowsFromUsersTableRO.rows.length, 500); + t.is(Object.keys(foundRowsFromUsersTableRO.rows[1]).length, 4); + t.is(Object.hasOwn(foundRowsFromUsersTableRO.rows[0], 'userid'), true); + t.is(Object.hasOwn(foundRowsFromUsersTableRO.rows[1], 'username'), true); + t.is(Object.hasOwn(foundRowsFromUsersTableRO.rows[2], 'created_at'), true); + + const foundRowsFromTransactionsTableResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTransactionsTableName}&page=1&perPage=500`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const foundRowsFromTransactionsTableRO = JSON.parse(foundRowsFromTransactionsTableResponse.text); + t.is(typeof foundRowsFromTransactionsTableRO, 'object'); + t.is(Object.hasOwn(foundRowsFromTransactionsTableRO, 'rows'), true); + t.is(Object.hasOwn(foundRowsFromTransactionsTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(foundRowsFromTransactionsTableRO, 'pagination'), true); + t.is(foundRowsFromTransactionsTableRO.rows.length, 500); + t.is(Object.keys(foundRowsFromTransactionsTableRO.rows[1]).length, 7); + t.is(Object.hasOwn(foundRowsFromTransactionsTableRO.rows[0], 'buyerid'), true); + t.is(Object.hasOwn(foundRowsFromTransactionsTableRO.rows[1], 'reviewerid'), true); + t.is(Object.hasOwn(foundRowsFromTransactionsTableRO.rows[2], 'transaction_date'), true); + + for (const row of foundRowsFromTransactionsTableRO.rows) { + t.is(Object.hasOwn(row, 'buyerid'), true); + const buyerId = row.buyerid; + t.is(typeof buyerId, 'object'); + t.is(Object.hasOwn(buyerId, 'userid'), true); + t.is(typeof buyerId.userid, 'number'); + const reviewerId = row.reviewerid; + t.is(typeof reviewerId, 'object'); + t.is(Object.hasOwn(reviewerId, 'userid'), true); + t.is(typeof reviewerId.userid, 'number'); + } + } catch (error) { + console.error(error); + throw error; + } }); diff --git a/backend/test/ava-tests/saas-tests/group-e2e.test.ts b/backend/test/ava-tests/saas-tests/group-e2e.test.ts index 8c57f472c..b9ba1b8e7 100644 --- a/backend/test/ava-tests/saas-tests/group-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/group-e2e.test.ts @@ -10,8 +10,8 @@ import { DatabaseService } from '../../../src/shared/database/database.service.j import cookieParser from 'cookie-parser'; import { AllExceptionsFilter } from '../../../src/exceptions/all-exceptions.filter.js'; import { - inviteUserInCompanyAndAcceptInvitation, - registerUserAndReturnUserInfo, + inviteUserInCompanyAndAcceptInvitation, + registerUserAndReturnUserInfo, } from '../../utils/register-user-and-return-user-info.js'; import { getTestData } from '../../utils/get-test-data.js'; import request from 'supertest'; @@ -29,1202 +29,1202 @@ let _testUtils: TestUtils; const mockFactory = new MockFactory(); test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); let currentTest = 'GET /groups'; test.serial(`${currentTest} should return all user groups`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const findAllUserGroups = await request(app.getHttpServer()) - .get(`/connection/groups/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(findAllUserGroups.status, 200); - - const result = JSON.parse(findAllUserGroups.text); - - t.is(result.length, 2); - - t.is(Object.hasOwn(result[1].group, 'users'), true); - t.is(Object.hasOwn(result[1].group.users[0], 'password'), false); - t.is(Object.hasOwn(result[0].group, 'title'), true); - t.is(Object.hasOwn(result[0].group, 'connection'), false); - t.is(result[1].accessLevel, AccessLevelEnum.edit); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const findAllUserGroups = await request(app.getHttpServer()) + .get(`/connection/groups/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(findAllUserGroups.status, 200); + + const result = JSON.parse(findAllUserGroups.text); + + t.is(result.length, 2); + + t.is(Object.hasOwn(result[1].group, 'users'), true); + t.is(Object.hasOwn(result[1].group.users[0], 'password'), false); + t.is(Object.hasOwn(result[0].group, 'title'), true); + t.is(Object.hasOwn(result[0].group, 'connection'), false); + t.is(result[1].accessLevel, AccessLevelEnum.edit); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'GET /group/users/:slug'; test.serial(`${currentTest} should return all users in current group`, async (t) => { - try { - const registeredUserInfo = await registerUserAndReturnUserInfo(app); - const firstUserToken = registeredUserInfo.token; - const firstUserEmail = registeredUserInfo.email; - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - const findAllUsersInGroup = await request(app.getHttpServer()) - .get(`/group/users/${createGroupRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(findAllUsersInGroup.status, 200); - const result = JSON.parse(findAllUsersInGroup.text); - t.is(result.length === 1, true); - - // t.is(result[0].isActive).toBe(true); - t.is(result[0].email, firstUserEmail.toLowerCase()); - } catch (e) { - console.error(e); - throw e; - } + try { + const registeredUserInfo = await registerUserAndReturnUserInfo(app); + const firstUserToken = registeredUserInfo.token; + const firstUserEmail = registeredUserInfo.email; + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + const findAllUsersInGroup = await request(app.getHttpServer()) + .get(`/group/users/${createGroupRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(findAllUsersInGroup.status, 200); + const result = JSON.parse(findAllUsersInGroup.text); + t.is(result.length === 1, true); + + // t.is(result[0].isActive).toBe(true); + t.is(result[0].email, firstUserEmail.toLowerCase()); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when group id is not real`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - createGroupRO.id = faker.string.uuid(); - const findAllUsersInGroup = await request(app.getHttpServer()) - .get(`/group/users/${createGroupRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(findAllUsersInGroup.status, 400); - const { message } = JSON.parse(findAllUsersInGroup.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + createGroupRO.id = faker.string.uuid(); + const findAllUsersInGroup = await request(app.getHttpServer()) + .get(`/group/users/${createGroupRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(findAllUsersInGroup.status, 400); + const { message } = JSON.parse(findAllUsersInGroup.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when group id not passed`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - createGroupRO.id = ''; - const findAllUsersInGroup = await request(app.getHttpServer()) - .get(`/group/users/${createGroupRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(findAllUsersInGroup.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + createGroupRO.id = ''; + const findAllUsersInGroup = await request(app.getHttpServer()) + .get(`/group/users/${createGroupRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(findAllUsersInGroup.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'PUT /group/user/:slug'; test.serial(`${currentTest} should return a group with new added user`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - firstUserToken, - undefined, - app, - undefined, - ); - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: createGroupRO.id, - }; - const findAllUsersInGroup = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const result = JSON.parse(findAllUsersInGroup.text).group; - t.is(findAllUsersInGroup.status, 200); - - t.is(result.title, newGroup1.title); - t.is(result.users.length, 2); - t.is(typeof result.users[1], 'object'); - - t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); - // t.is(result.users[0].isActive).toBe(true); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + firstUserToken, + undefined, + app, + undefined, + ); + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: createGroupRO.id, + }; + const findAllUsersInGroup = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const result = JSON.parse(findAllUsersInGroup.text).group; + t.is(findAllUsersInGroup.status, 200); + + t.is(result.title, newGroup1.title); + t.is(result.users.length, 2); + t.is(typeof result.users[1], 'object'); + + t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); + // t.is(result.users[0].isActive).toBe(true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when groupId not passed in request`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - firstUserToken, - undefined, - app, - undefined, - ); - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: undefined, - }; - const addUserInGroup = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup.status, 400); - const { message } = JSON.parse(addUserInGroup.text); - t.is(message, Messages.GROUP_ID_MISSING); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + firstUserToken, + undefined, + app, + undefined, + ); + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: undefined, + }; + const addUserInGroup = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup.status, 400); + const { message } = JSON.parse(addUserInGroup.text); + t.is(message, Messages.GROUP_ID_MISSING); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when user email not passed in request`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - const requestBody = { - email: undefined, - groupId: createGroupRO.id, - }; - const addUserInGroup = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup.status, 400); - const { message } = JSON.parse(addUserInGroup.text); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + const requestBody = { + email: undefined, + groupId: createGroupRO.id, + }; + const addUserInGroup = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup.status, 400); + const { message } = JSON.parse(addUserInGroup.text); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when groupId is incorrect`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - firstUserToken, - undefined, - app, - undefined, - ); - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - createGroupRO.id = faker.string.uuid(); - - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: createGroupRO.id, - }; - const addUserInGroup = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup.status, 400); - const { message } = JSON.parse(addUserInGroup.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + firstUserToken, + undefined, + app, + undefined, + ); + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + createGroupRO.id = faker.string.uuid(); + + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: createGroupRO.id, + }; + const addUserInGroup = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup.status, 400); + const { message } = JSON.parse(addUserInGroup.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when add a user what been already added in this group`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - firstUserToken, - undefined, - app, - undefined, - ); - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - let createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - createConnectionRO = JSON.parse(createConnectionResponse.text); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: createGroupRO.id, - }; - - const addUserInGroup1 = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup1.status, 200); - - const addUserInGroup2 = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup2.status, 400); - const { message } = JSON.parse(addUserInGroup2.text); - t.is(message, Messages.USER_ALREADY_ADDED); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + firstUserToken, + undefined, + app, + undefined, + ); + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + let createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + createConnectionRO = JSON.parse(createConnectionResponse.text); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: createGroupRO.id, + }; + + const addUserInGroup1 = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup1.status, 200); + + const addUserInGroup2 = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup2.status, 400); + const { message } = JSON.parse(addUserInGroup2.text); + t.is(message, Messages.USER_ALREADY_ADDED); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'DELETE /group'; test.serial(`${currentTest} should return an delete result`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - const deleteResult = await request(app.getHttpServer()) - .delete(`/group/${createGroupRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const deleteResultRO = JSON.parse(deleteResult.text); - t.is(deleteResult.status, 200); - t.is(typeof deleteResult, 'object'); - t.is(deleteResultRO.isMain, false); - - const response = await request(app.getHttpServer()) - .get(`/connection/groups/${createConnectionRO.id}`) - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(response.status, 200); - const result = JSON.parse(response.text); - const _groupId = result[0].group.id; - t.is(result.length, 1); - - t.is(result[0].group.title, 'Admin'); - t.is(result[0].accessLevel, AccessLevelEnum.edit); - - const index = result - .map((e) => { - return e.group.title; - }) - .indexOf('Admin'); - - t.is(index >= 0, true); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + const deleteResult = await request(app.getHttpServer()) + .delete(`/group/${createGroupRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const deleteResultRO = JSON.parse(deleteResult.text); + t.is(deleteResult.status, 200); + t.is(typeof deleteResult, 'object'); + t.is(deleteResultRO.isMain, false); + + const response = await request(app.getHttpServer()) + .get(`/connection/groups/${createConnectionRO.id}`) + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(response.status, 200); + const result = JSON.parse(response.text); + const _groupId = result[0].group.id; + t.is(result.length, 1); + + t.is(result[0].group.title, 'Admin'); + t.is(result[0].accessLevel, AccessLevelEnum.edit); + + const index = result + .map((e) => { + return e.group.title; + }) + .indexOf('Admin'); + + t.is(index >= 0, true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return throw an exception when groupId is incorrect`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - createGroupRO.id = faker.string.uuid(); - const deleteResult = await request(app.getHttpServer()) - .delete(`/group/${createGroupRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteResult.status, 400); - const { message } = JSON.parse(deleteResult.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + createGroupRO.id = faker.string.uuid(); + const deleteResult = await request(app.getHttpServer()) + .delete(`/group/${createGroupRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteResult.status, 400); + const { message } = JSON.parse(deleteResult.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when groupId is not passed in request`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - createGroupRO.id = ''; - const deleteResult = await request(app.getHttpServer()) - .delete(`/group/${createGroupRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteResult.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + createGroupRO.id = ''; + const deleteResult = await request(app.getHttpServer()) + .delete(`/group/${createGroupRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteResult.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'PUT /group/user/delete'; test.serial(`${currentTest} should return a group without deleted user`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - firstUserToken, - undefined, - app, - undefined, - ); - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: createGroupRO.id, - }; - const addUserInGroup = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup.status, 200); - let result = JSON.parse(addUserInGroup.text).group; - - t.is(result.title, newGroup1.title); - t.is(result.users.length, 2); - t.is(typeof result.users[1], 'object'); - - t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); - // t.is(result.users[0].isActive).toBe(true); - - const removeUserFromGroup = await request(app.getHttpServer()) - .put(`/group/user/delete/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - result = JSON.parse(removeUserFromGroup.text); - - t.is(typeof result, 'object'); - t.is(result.title, newGroup1.title); - - t.is(Object.hasOwn(result, 'users'), true); - t.is(typeof result.users, 'object'); - t.is(result.users.length, 1); - - // t.is(result.users[0].isActive).toBe(true); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + firstUserToken, + undefined, + app, + undefined, + ); + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: createGroupRO.id, + }; + const addUserInGroup = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup.status, 200); + let result = JSON.parse(addUserInGroup.text).group; + + t.is(result.title, newGroup1.title); + t.is(result.users.length, 2); + t.is(typeof result.users[1], 'object'); + + t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); + // t.is(result.users[0].isActive).toBe(true); + + const removeUserFromGroup = await request(app.getHttpServer()) + .put(`/group/user/delete/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + result = JSON.parse(removeUserFromGroup.text); + + t.is(typeof result, 'object'); + t.is(result.title, newGroup1.title); + + t.is(Object.hasOwn(result, 'users'), true); + t.is(typeof result.users, 'object'); + t.is(result.users.length, 1); + + // t.is(result.users[0].isActive).toBe(true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error, when group id not passed in request`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - firstUserToken, - undefined, - app, - undefined, - ); - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: createGroupRO.id, - }; - const addUserInGroup = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup.status, 200); - const result = JSON.parse(addUserInGroup.text).group; - - t.is(result.title, newGroup1.title); - t.is(result.users.length, 2); - t.is(typeof result.users[1], 'object'); - - t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); - // t.is(result.users[0].isActive).toBe(true); - - requestBody.groupId = undefined; - const removeUserFromGroup = await request(app.getHttpServer()) - .put(`/group/user/delete/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(removeUserFromGroup.text); - t.is(removeUserFromGroup.status, 400); - t.is(message, Messages.GROUP_ID_MISSING); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + firstUserToken, + undefined, + app, + undefined, + ); + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: createGroupRO.id, + }; + const addUserInGroup = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup.status, 200); + const result = JSON.parse(addUserInGroup.text).group; + + t.is(result.title, newGroup1.title); + t.is(result.users.length, 2); + t.is(typeof result.users[1], 'object'); + + t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); + // t.is(result.users[0].isActive).toBe(true); + + requestBody.groupId = undefined; + const removeUserFromGroup = await request(app.getHttpServer()) + .put(`/group/user/delete/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(removeUserFromGroup.text); + t.is(removeUserFromGroup.status, 400); + t.is(message, Messages.GROUP_ID_MISSING); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error, when email is not passed in request`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - firstUserToken, - undefined, - app, - undefined, - ); - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: createGroupRO.id, - }; - const addUserInGroup = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup.status, 200); - const result = JSON.parse(addUserInGroup.text).group; - - t.is(result.title, newGroup1.title); - t.is(result.users.length, 2); - t.is(typeof result.users[1], 'object'); - - t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); - // t.is(result.users[0].isActive).toBe(true); - - requestBody.email = undefined; - const removeUserFromGroup = await request(app.getHttpServer()) - .put(`/group/user/delete/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(removeUserFromGroup.text); - t.is(removeUserFromGroup.status, 400); - // t.is(message, ErrorsMessages.VALIDATION_FAILED); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + firstUserToken, + undefined, + app, + undefined, + ); + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: createGroupRO.id, + }; + const addUserInGroup = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup.status, 200); + const result = JSON.parse(addUserInGroup.text).group; + + t.is(result.title, newGroup1.title); + t.is(result.users.length, 2); + t.is(typeof result.users[1], 'object'); + + t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); + // t.is(result.users[0].isActive).toBe(true); + + requestBody.email = undefined; + const removeUserFromGroup = await request(app.getHttpServer()) + .put(`/group/user/delete/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(removeUserFromGroup.text); + t.is(removeUserFromGroup.status, 400); + // t.is(message, ErrorsMessages.VALIDATION_FAILED); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error, when there is no this email in database`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - firstUserToken, - undefined, - app, - undefined, - ); - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: createGroupRO.id, - }; - - const addUserInGroup = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup.status, 200); - - requestBody.email = faker.internet.email(); - const removeUserFromGroup = await request(app.getHttpServer()) - .put(`/group/user/delete/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(removeUserFromGroup.text); - t.is(removeUserFromGroup.status, 400); - t.is(message, Messages.USER_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + firstUserToken, + undefined, + app, + undefined, + ); + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: createGroupRO.id, + }; + + const addUserInGroup = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup.status, 200); + + requestBody.email = faker.internet.email(); + const removeUserFromGroup = await request(app.getHttpServer()) + .put(`/group/user/delete/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(removeUserFromGroup.text); + t.is(removeUserFromGroup.status, 400); + t.is(message, Messages.USER_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error, when group id is incorrect`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - firstUserToken, - undefined, - app, - undefined, - ); - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - - const requestBody = { - email: secondUserRegisterInfo.email, - groupId: createGroupRO.id, - }; - const addUserInGroup = await request(app.getHttpServer()) - .put(`/group/user/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addUserInGroup.status, 200); - const result = JSON.parse(addUserInGroup.text).group; - - t.is(result.title, newGroup1.title); - t.is(result.users.length, 2); - t.is(typeof result.users[1], 'object'); - - t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); - - requestBody.groupId = faker.string.uuid(); - const removeUserFromGroup = await request(app.getHttpServer()) - .put(`/group/user/delete/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(removeUserFromGroup.text); - t.is(removeUserFromGroup.status, 400); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const secondUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + firstUserToken, + undefined, + app, + undefined, + ); + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + + const requestBody = { + email: secondUserRegisterInfo.email, + groupId: createGroupRO.id, + }; + const addUserInGroup = await request(app.getHttpServer()) + .put(`/group/user/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addUserInGroup.status, 200); + const result = JSON.parse(addUserInGroup.text).group; + + t.is(result.title, newGroup1.title); + t.is(result.users.length, 2); + t.is(typeof result.users[1], 'object'); + + t.is(result.users[1].email, secondUserRegisterInfo.email.toLowerCase()); + + requestBody.groupId = faker.string.uuid(); + const removeUserFromGroup = await request(app.getHttpServer()) + .put(`/group/user/delete/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(removeUserFromGroup.text); + t.is(removeUserFromGroup.status, 400); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error, trying delete last user from admin group`, async (t) => { - try { - const firstUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const firstUserToken = firstUserRegisterInfo.token; - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - let createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection2) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const _createGroupRO = JSON.parse(createGroupResponse.text); - const groupId = createConnectionRO.groups[0].id; - const requestBody = { - email: firstUserRegisterInfo.email, - groupId: groupId, - }; - - const removeUserFromGroup = await request(app.getHttpServer()) - .put(`/group/user/delete/`) - .send(requestBody) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(removeUserFromGroup.text); - t.is(removeUserFromGroup.status, 403); - t.is(message, Messages.CANT_DELETE_LAST_USER); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const firstUserToken = firstUserRegisterInfo.token; + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + let createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection2) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const _createGroupRO = JSON.parse(createGroupResponse.text); + const groupId = createConnectionRO.groups[0].id; + const requestBody = { + email: firstUserRegisterInfo.email, + groupId: groupId, + }; + + const removeUserFromGroup = await request(app.getHttpServer()) + .put(`/group/user/delete/`) + .send(requestBody) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(removeUserFromGroup.text); + t.is(removeUserFromGroup.status, 403); + t.is(message, Messages.CANT_DELETE_LAST_USER); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'PUT /group/title/'; test.serial(`${currentTest} should return a group with new title`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnection) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 201); - - const createGroupRO = JSON.parse(createGroupResponse.text); - const groupId = createGroupRO.id; - - const groupUpdateData = { - title: 'Updated title', - groupId: groupId, - }; - - const updateGroupResponse = await request(app.getHttpServer()) - .put(`/group/title/`) - .send(groupUpdateData) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(updateGroupResponse.status, 200); - - const updateGroupTitleRO = JSON.parse(updateGroupResponse.text); - t.is(updateGroupTitleRO.title, groupUpdateData.title); - } catch (e) { - console.error(e); - throw e; - } + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { newConnection, newConnection2, newGroup1 } = getTestData(mockFactory); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createGroupResponse.status, 201); + + const createGroupRO = JSON.parse(createGroupResponse.text); + const groupId = createGroupRO.id; + + const groupUpdateData = { + title: 'Updated title', + groupId: groupId, + }; + + const updateGroupResponse = await request(app.getHttpServer()) + .put(`/group/title/`) + .send(groupUpdateData) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(updateGroupResponse.status, 200); + + const updateGroupTitleRO = JSON.parse(updateGroupResponse.text); + t.is(updateGroupTitleRO.title, groupUpdateData.title); + } catch (e) { + console.error(e); + throw e; + } }); diff --git a/backend/test/ava-tests/saas-tests/permissions-e2e.test.ts b/backend/test/ava-tests/saas-tests/permissions-e2e.test.ts index 93ed15561..907bfceb5 100644 --- a/backend/test/ava-tests/saas-tests/permissions-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/permissions-e2e.test.ts @@ -28,256 +28,256 @@ let _testUtils: TestUtils; const mockFactory = new MockFactory(); test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); let currentTest = 'PUT permissions/:slug'; test.serial(`${currentTest} should return created permissions`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { newConnectionInDocker, newGroup1 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnectionInDocker) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { newConnectionInDocker, newGroup1 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnectionInDocker) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createGroupRO = JSON.parse(createGroupResponse.text); - t.is(createGroupResponse.status, 201); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + t.is(createGroupResponse.status, 201); - let connectionAccessLevel = AccessLevelEnum.none; - let groupAccesssLevel = AccessLevelEnum.edit; - let permissionsDTO = mockFactory.generateInternalPermissions( - createConnectionRO.id, - createGroupRO.id, - connectionAccessLevel, - groupAccesssLevel, - ); - let createPermissionsResponse = await request(app.getHttpServer()) - .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) - .send(permissionsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createPermissionsResponse.status, 200); - let createPermissionsRO = JSON.parse(createPermissionsResponse.text); - let { connection: connectionDTO, group: groupDTO, tables: tablesDTO } = permissionsDTO.permissions; - let { connection, group, tables } = createPermissionsRO; - t.is(connection.accessLevel, connectionDTO.accessLevel); - t.is(group.accessLevel, groupDTO.accessLevel); - t.is(connection.connectionId, connectionDTO.connectionId); - t.is(group.groupId, groupDTO.groupId); - for (const table of tables) { - const tableInDto = tablesDTO.find((t) => t.tableName === table.tableName); - for (const key in table.accessLevel) { - t.is(table.accessLevel[key], tableInDto.accessLevel[key]); - } - } + let connectionAccessLevel = AccessLevelEnum.none; + let groupAccesssLevel = AccessLevelEnum.edit; + let permissionsDTO = mockFactory.generateInternalPermissions( + createConnectionRO.id, + createGroupRO.id, + connectionAccessLevel, + groupAccesssLevel, + ); + let createPermissionsResponse = await request(app.getHttpServer()) + .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) + .send(permissionsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createPermissionsResponse.status, 200); + let createPermissionsRO = JSON.parse(createPermissionsResponse.text); + let { connection: connectionDTO, group: groupDTO, tables: tablesDTO } = permissionsDTO.permissions; + let { connection, group, tables } = createPermissionsRO; + t.is(connection.accessLevel, connectionDTO.accessLevel); + t.is(group.accessLevel, groupDTO.accessLevel); + t.is(connection.connectionId, connectionDTO.connectionId); + t.is(group.groupId, groupDTO.groupId); + for (const table of tables) { + const tableInDto = tablesDTO.find((t) => t.tableName === table.tableName); + for (const key in table.accessLevel) { + t.is(table.accessLevel[key], tableInDto.accessLevel[key]); + } + } - connectionAccessLevel = AccessLevelEnum.readonly; - groupAccesssLevel = AccessLevelEnum.none; - permissionsDTO = mockFactory.generateInternalPermissions( - createConnectionRO.id, - createGroupRO.id, - connectionAccessLevel, - groupAccesssLevel, - ); + connectionAccessLevel = AccessLevelEnum.readonly; + groupAccesssLevel = AccessLevelEnum.none; + permissionsDTO = mockFactory.generateInternalPermissions( + createConnectionRO.id, + createGroupRO.id, + connectionAccessLevel, + groupAccesssLevel, + ); - createPermissionsResponse = await request(app.getHttpServer()) - .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) - .send(permissionsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - createPermissionsRO = JSON.parse(createPermissionsResponse.text); - t.is(createPermissionsResponse.status, 200); + createPermissionsResponse = await request(app.getHttpServer()) + .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) + .send(permissionsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + createPermissionsRO = JSON.parse(createPermissionsResponse.text); + t.is(createPermissionsResponse.status, 200); - t.is(createPermissionsRO.connection.accessLevel, connectionAccessLevel); + t.is(createPermissionsRO.connection.accessLevel, connectionAccessLevel); - t.is(createPermissionsRO.group.accessLevel, groupAccesssLevel); + t.is(createPermissionsRO.group.accessLevel, groupAccesssLevel); - tables = createPermissionsRO.tables; - tablesDTO = permissionsDTO.permissions.tables; - for (const table of tables) { - const tableInDto = tablesDTO.find((t) => t.tableName === table.tableName); - for (const key in table.accessLevel) { - t.is(table.accessLevel[key], tableInDto.accessLevel[key]); - } - } - } catch (e) { - console.error(e); - throw e; - } + tables = createPermissionsRO.tables; + tablesDTO = permissionsDTO.permissions.tables; + for (const table of tables) { + const tableInDto = tablesDTO.find((t) => t.tableName === table.tableName); + for (const key in table.accessLevel) { + t.is(table.accessLevel[key], tableInDto.accessLevel[key]); + } + } + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when groupId not passed`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { newConnectionInDocker, newGroup1 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnectionInDocker) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - let createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { newConnectionInDocker, newGroup1 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnectionInDocker) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + let createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createGroupRO = JSON.parse(createGroupResponse.text); - t.is(createGroupResponse.status, 201); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + t.is(createGroupResponse.status, 201); - let connectionAccessLevel = AccessLevelEnum.none; - let groupAccesssLevel = AccessLevelEnum.edit; - let permissionsDTO = mockFactory.generateInternalPermissions( - createConnectionRO.id, - createGroupRO.id, - connectionAccessLevel, - groupAccesssLevel, - ); - createGroupRO.id = ''; - let createPermissionsResponse = await request(app.getHttpServer()) - .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) - .send(permissionsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createPermissionsResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + let connectionAccessLevel = AccessLevelEnum.none; + let groupAccesssLevel = AccessLevelEnum.edit; + let permissionsDTO = mockFactory.generateInternalPermissions( + createConnectionRO.id, + createGroupRO.id, + connectionAccessLevel, + groupAccesssLevel, + ); + createGroupRO.id = ''; + let createPermissionsResponse = await request(app.getHttpServer()) + .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) + .send(permissionsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createPermissionsResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when groupId passed in request is incorrect`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { newConnectionInDocker, newGroup1 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnectionInDocker) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - let createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { newConnectionInDocker, newGroup1 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnectionInDocker) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + let createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createGroupRO = JSON.parse(createGroupResponse.text); - t.is(createGroupResponse.status, 201); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + t.is(createGroupResponse.status, 201); - let connectionAccessLevel = AccessLevelEnum.none; - let groupAccesssLevel = AccessLevelEnum.edit; - let permissionsDTO = mockFactory.generateInternalPermissions( - createConnectionRO.id, - createGroupRO.id, - connectionAccessLevel, - groupAccesssLevel, - ); - createGroupRO.id = faker.string.uuid(); - let createPermissionsResponse = await request(app.getHttpServer()) - .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) - .send(permissionsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); + let connectionAccessLevel = AccessLevelEnum.none; + let groupAccesssLevel = AccessLevelEnum.edit; + let permissionsDTO = mockFactory.generateInternalPermissions( + createConnectionRO.id, + createGroupRO.id, + connectionAccessLevel, + groupAccesssLevel, + ); + createGroupRO.id = faker.string.uuid(); + let createPermissionsResponse = await request(app.getHttpServer()) + .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) + .send(permissionsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const createPermissionsRO = JSON.parse(createPermissionsResponse.text); - t.is(createPermissionsResponse.status, 400); - t.is(createPermissionsRO.message, Messages.GROUP_NOT_FROM_THIS_CONNECTION); - } catch (e) { - console.error(e); - throw e; - } + const createPermissionsRO = JSON.parse(createPermissionsResponse.text); + t.is(createPermissionsResponse.status, 400); + t.is(createPermissionsRO.message, Messages.GROUP_NOT_FROM_THIS_CONNECTION); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when connectionId is incorrect`, async (t) => { - try { - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { newConnectionInDocker, newGroup1 } = getTestData(mockFactory); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(newConnectionInDocker) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - let createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); + try { + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { newConnectionInDocker, newGroup1 } = getTestData(mockFactory); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(newConnectionInDocker) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + let createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${createConnectionRO.id}`) - .send(newGroup1) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createGroupRO = JSON.parse(createGroupResponse.text); - t.is(createGroupResponse.status, 201); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${createConnectionRO.id}`) + .send(newGroup1) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + t.is(createGroupResponse.status, 201); - let connectionAccessLevel = AccessLevelEnum.none; - let groupAccesssLevel = AccessLevelEnum.edit; - let permissionsDTO = mockFactory.generateInternalPermissions( - createConnectionRO.id, - createGroupRO.id, - connectionAccessLevel, - groupAccesssLevel, - ); - permissionsDTO.permissions.connection.connectionId = faker.string.uuid(); - let createPermissionsResponse = await request(app.getHttpServer()) - .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) - .send(permissionsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createPermissionsResponse.status, 400); - const { message } = JSON.parse(createPermissionsResponse.text); - t.is(message, Messages.GROUP_NOT_FROM_THIS_CONNECTION); - } catch (e) { - console.error(e); - throw e; - } + let connectionAccessLevel = AccessLevelEnum.none; + let groupAccesssLevel = AccessLevelEnum.edit; + let permissionsDTO = mockFactory.generateInternalPermissions( + createConnectionRO.id, + createGroupRO.id, + connectionAccessLevel, + groupAccesssLevel, + ); + permissionsDTO.permissions.connection.connectionId = faker.string.uuid(); + let createPermissionsResponse = await request(app.getHttpServer()) + .put(`/permissions/${createGroupRO.id}?connectionId=${createConnectionRO.id}`) + .send(permissionsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createPermissionsResponse.status, 400); + const { message } = JSON.parse(createPermissionsResponse.text); + t.is(message, Messages.GROUP_NOT_FROM_THIS_CONNECTION); + } catch (e) { + console.error(e); + throw e; + } }); diff --git a/backend/test/ava-tests/saas-tests/postgres-with-binary-e2e.test.ts b/backend/test/ava-tests/saas-tests/postgres-with-binary-e2e.test.ts index db07271ac..0d14edc74 100644 --- a/backend/test/ava-tests/saas-tests/postgres-with-binary-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/postgres-with-binary-e2e.test.ts @@ -28,106 +28,106 @@ let _testUtils: TestUtils; let currentTest; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = ''; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const connectionParamsCopy = { - ...connectionToTestDB, - }; - - const testTableName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; - const testTableColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; - const testTableSecondColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; - const Knex = getTestKnex(connectionParamsCopy); - await Knex.schema.createTable(testTableName, (table) => { - table.increments(); - table.binary(testTableColumnName); - table.string(testTableSecondColumnName); - table.timestamps(); - }); - - const testDataForInsert = { - [testTableColumnName]: hexToBinary('6168616c6169206d6168616c6169'), - [testTableSecondColumnName]: 'test', - }; - - await Knex(testTableName).insert({ - ...testDataForInsert, - }); - - for (let i = 0; i < 8; i++) { - await Knex(testTableName).insert({ - [testTableColumnName]: hexToBinary(`6168616c616${i}206d6168616c6169`), - [testTableSecondColumnName]: `test_${i}`, - }); - } - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - const getTableRowsWithSearchResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${getTableRowsRO.rows[0][testTableColumnName]}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsWithSearchRO = JSON.parse(getTableRowsWithSearchResponse.text); - t.is(getTableRowsWithSearchRO.rows.length, 1); - t.is(getTableRowsWithSearchRO.rows[0][testTableColumnName], getTableRowsRO.rows[0][testTableColumnName]); - - t.pass(); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const connectionParamsCopy = { + ...connectionToTestDB, + }; + + const testTableName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; + const testTableColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; + const testTableSecondColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; + const Knex = getTestKnex(connectionParamsCopy); + await Knex.schema.createTable(testTableName, (table) => { + table.increments(); + table.binary(testTableColumnName); + table.string(testTableSecondColumnName); + table.timestamps(); + }); + + const testDataForInsert = { + [testTableColumnName]: hexToBinary('6168616c6169206d6168616c6169'), + [testTableSecondColumnName]: 'test', + }; + + await Knex(testTableName).insert({ + ...testDataForInsert, + }); + + for (let i = 0; i < 8; i++) { + await Knex(testTableName).insert({ + [testTableColumnName]: hexToBinary(`6168616c616${i}206d6168616c6169`), + [testTableSecondColumnName]: `test_${i}`, + }); + } + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + const getTableRowsWithSearchResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${getTableRowsRO.rows[0][testTableColumnName]}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsWithSearchRO = JSON.parse(getTableRowsWithSearchResponse.text); + t.is(getTableRowsWithSearchRO.rows.length, 1); + t.is(getTableRowsWithSearchRO.rows[0][testTableColumnName], getTableRowsRO.rows[0][testTableColumnName]); + + t.pass(); + } catch (e) { + console.error(e); + throw e; + } }); diff --git a/backend/test/ava-tests/saas-tests/table-cassandra.e2e.test.ts b/backend/test/ava-tests/saas-tests/table-cassandra.e2e.test.ts index 2e3d16ebf..e1ae7a0c3 100644 --- a/backend/test/ava-tests/saas-tests/table-cassandra.e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/table-cassandra.e2e.test.ts @@ -39,4053 +39,4053 @@ const testTables: Array = []; let currentTest; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication() as any; - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication() as any; + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /connection/tables/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTablesRO = JSON.parse(getTablesResponse.text); - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.length > 0, true); - - const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); - - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); - t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); - t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); - t.is(getTablesRO[testTableIndex].table, testTableName); - t.is(getTablesRO[testTableIndex].permissions.visibility, true); - t.is(getTablesRO[testTableIndex].permissions.readonly, false); - t.is(getTablesRO[testTableIndex].permissions.add, true); - t.is(getTablesRO[testTableIndex].permissions.delete, true); - t.is(getTablesRO[testTableIndex].permissions.edit, true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTablesRO = JSON.parse(getTablesResponse.text); + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.length > 0, true); + + const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); + + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); + t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); + t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); + t.is(getTablesRO[testTableIndex].table, testTableName); + t.is(getTablesRO[testTableIndex].permissions.visibility, true); + t.is(getTablesRO[testTableIndex].permissions.readonly, false); + t.is(getTablesRO[testTableIndex].permissions.add, true); + t.is(getTablesRO[testTableIndex].permissions.delete, true); + t.is(getTablesRO[testTableIndex].permissions.edit, true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connectionId not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = ''; - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = ''; + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connection id is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = faker.string.uuid(); - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 400); - const { message } = JSON.parse(getTablesResponse.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = faker.string.uuid(); + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 400); + const { message } = JSON.parse(getTablesResponse.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return rows of selected table without search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(getTableRowsResponse.status, 200); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(Object.hasOwn(getTableRowsRO, 'large_dataset'), true); - t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(getTableRowsResponse.status, 200); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(Object.hasOwn(getTableRowsRO, 'large_dataset'), true); + t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return rows of selected table with search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); - - t.is(createTableSettingsResponse.status, 201); - - const searchedDescription = insertedSearchedIds[0].id; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(getTableRowsResponse.status, 200); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0].id, searchedDescription); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); + + t.is(createTableSettingsResponse.status, 201); + + const searchedDescription = insertedSearchedIds[0].id; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(getTableRowsResponse.status, 200); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0].id, searchedDescription); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=1, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Content-Type', 'application/json') - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'uuid'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'uuid'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=3, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'uuid'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 3); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'uuid'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 3); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'uuid'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'uuid'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'uuid'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'uuid'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by DESC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(getTableRowsResponse.status, 200); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - - const ages = getTableRowsRO.rows.map((row) => row.age); - for (let i = 0; i < ages.length - 1; i++) { - t.true( - ages[i] >= ages[i + 1], - `Age at index ${i} (${ages[i]}) should be >= age at index ${i + 1} (${ages[i + 1]})`, - ); - } - - const highestAgeRows = getTableRowsRO.rows.filter((row) => row.age >= 90); - t.true(highestAgeRows.length >= 2, 'Should have at least 2 rows with age >= 90'); - t.true( - highestAgeRows.every((row) => row.name === testSearchedUserName), - 'High age rows should have the test user name', - ); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(getTableRowsResponse.status, 200); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + + const ages = getTableRowsRO.rows.map((row) => row.age); + for (let i = 0; i < ages.length - 1; i++) { + t.true( + ages[i] >= ages[i + 1], + `Age at index ${i} (${ages[i]}) should be >= age at index ${i + 1} (${ages[i + 1]})`, + ); + } + + const highestAgeRows = getTableRowsRO.rows.filter((row) => row.age >= 90); + t.true(highestAgeRows.length >= 2, 'Should have at least 2 rows with age >= 90'); + t.true( + highestAgeRows.every((row) => row.name === testSearchedUserName), + 'High age rows should have the test user name', + ); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by ASC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.ASC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - - // Check that rows are sorted by age in ascending order - const ages = getTableRowsRO.rows.map((row) => row.age); - for (let i = 0; i < ages.length - 1; i++) { - t.true( - ages[i] <= ages[i + 1], - `Age at index ${i} (${ages[i]}) should be <= age at index ${i + 1} (${ages[i + 1]})`, - ); - } - - // Verify the youngest test user is near the beginning - const lowestAgeRow = getTableRowsRO.rows.find((row) => row.name === testSearchedUserName && row.age === 14); - t.truthy(lowestAgeRow, 'Should find the test user with age 14'); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.ASC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + + // Check that rows are sorted by age in ascending order + const ages = getTableRowsRO.rows.map((row) => row.age); + for (let i = 0; i < ages.length - 1; i++) { + t.true( + ages[i] <= ages[i + 1], + `Age at index ${i} (${ages[i]}) should be <= age at index ${i + 1} (${ages[i + 1]})`, + ); + } + + // Verify the youngest test user is near the beginning + const lowestAgeRow = getTableRowsRO.rows.find((row) => row.name === testSearchedUserName && row.age === 14); + t.truthy(lowestAgeRow, 'Should find the test user with age 14'); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and with pagination and with sorting + `${currentTest} without search and with pagination and with sorting should return all found rows with sorting ports by DESC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(getTableRowsResponse.status, 200); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - - // Check that rows are sorted by age in descending order - const ages = getTableRowsRO.rows.map((row) => row.age); - for (let i = 0; i < ages.length - 1; i++) { - t.true( - ages[i] >= ages[i + 1], - `Age at index ${i} (${ages[i]}) should be >= age at index ${i + 1} (${ages[i + 1]})`, - ); - } - - // Verify the oldest test user is near the beginning - const lowestAgeRow = getTableRowsRO.rows.find((row) => row.name === testSearchedUserName && row.age === 90); - t.truthy(lowestAgeRow, 'Should find the test user with age 90'); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(getTableRowsResponse.status, 200); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + + // Check that rows are sorted by age in descending order + const ages = getTableRowsRO.rows.map((row) => row.age); + for (let i = 0; i < ages.length - 1; i++) { + t.true( + ages[i] >= ages[i + 1], + `Age at index ${i} (${ages[i]}) should be >= age at index ${i + 1} (${ages[i + 1]})`, + ); + } + + // Verify the oldest test user is near the beginning + const lowestAgeRow = getTableRowsRO.rows.find((row) => row.name === testSearchedUserName && row.age === 90); + t.truthy(lowestAgeRow, 'Should find the test user with age 90'); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting age by ASC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - - const ages = getTableRowsRO.rows.map((row) => row.age); - for (let i = 0; i < ages.length - 1; i++) { - t.true( - ages[i] <= ages[i + 1], - `Age at index ${i} (${ages[i]}) should be <= age at index ${i + 1} (${ages[i + 1]})`, - ); - } - - const lowestAgeRow = getTableRowsRO.rows.find((row) => row.name === testSearchedUserName && row.age === 14); - t.truthy(lowestAgeRow, 'Should find the test user with age 14'); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting age by ASC and with pagination page=1, perPage=2`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + + const ages = getTableRowsRO.rows.map((row) => row.age); + for (let i = 0; i < ages.length - 1; i++) { + t.true( + ages[i] <= ages[i + 1], + `Age at index ${i} (${ages[i]}) should be <= age at index ${i + 1} (${ages[i + 1]})`, + ); + } + + const lowestAgeRow = getTableRowsRO.rows.find((row) => row.name === testSearchedUserName && row.age === 14); + t.truthy(lowestAgeRow, 'Should find the test user with age 14'); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - - const ages = getTableRowsRO.rows.map((row) => row.age); - for (let i = 0; i < ages.length - 1; i++) { - t.true( - ages[i] >= ages[i + 1], - `Age at index ${i} (${ages[i]}) should be >= age at index ${i + 1} (${ages[i + 1]})`, - ); - } - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + + const ages = getTableRowsRO.rows.map((row) => row.age); + for (let i = 0; i < ages.length - 1; i++) { + t.true( + ages[i] >= ages[i + 1], + `Age at index ${i} (${ages[i]}) should be >= age at index ${i + 1} (${ages[i + 1]})`, + ); + } + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(getTableRowsResponse.status, 200); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - const ages = getTableRowsRO.rows.map((row) => row.age); - for (let i = 0; i < ages.length - 1; i++) { - t.true( - ages[i] >= ages[i + 1], - `Age at index ${i} (${ages[i]}) should be >= age at index ${i + 1} (${ages[i + 1]})`, - ); - } - - const highestAgeRow = getTableRowsRO.rows.find((row) => row.name === testSearchedUserName && row.age === 95); - t.truthy(highestAgeRow, 'Should find the test user with age 95'); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(getTableRowsResponse.status, 200); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + const ages = getTableRowsRO.rows.map((row) => row.age); + for (let i = 0; i < ages.length - 1; i++) { + t.true( + ages[i] >= ages[i + 1], + `Age at index ${i} (${ages[i]}) should be >= age at index ${i + 1} (${ages[i + 1]})`, + ); + } + + const highestAgeRow = getTableRowsRO.rows.find((row) => row.name === testSearchedUserName && row.age === 95); + t.truthy(highestAgeRow, 'Should find the test user with age 95'); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const _createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); - - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0].age, 14); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const _createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); + + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0].age, 14); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0].age, 14); - t.is(getTableRowsRO.rows[1].age, 90); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0].age, 14); + t.is(getTableRowsRO.rows[1].age, 90); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0].age, 95); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0].age, 95); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and filtering in body`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'age'; - const fieldvalue = '80'; - - const filters = { - [fieldname]: { gt: fieldvalue }, - }; - - const getTableRowsResponse = await request(app.getHttpServer()) - .post( - `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .send({ filters }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].age, 95); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].age, 90); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'age'; + const fieldvalue = '80'; + + const filters = { + [fieldname]: { gt: fieldvalue }, + }; + + const getTableRowsResponse = await request(app.getHttpServer()) + .post( + `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .send({ filters }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].age, 95); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].age, 90); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=10 and DESC sorting and filtering'`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'age'; - const fieldvalue = '18'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].age, 14); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 10); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'age'; + const fieldvalue = '18'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].age, 14); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 10); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'age'; - const fieldvalue = '96'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].age, 14); - - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'age'; + const fieldvalue = '96'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].age, 14); + + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'age'; - const fieldLtvalue = '96'; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 400); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'age'; + const fieldLtvalue = '96'; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 400); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = faker.lorem.words(1); - const fieldLtvalue = '96'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTablesRO = JSON.parse(getTableRowsResponse.text); - t.is(getTablesRO.rows.length, 2); - t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTablesRO, 'pagination'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = faker.lorem.words(1); + const fieldLtvalue = '96'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTablesRO = JSON.parse(getTableRowsResponse.text); + t.is(getTablesRO.rows.length, 2); + t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTablesRO, 'pagination'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 200); - const getTableStructureRO = JSON.parse(getTableStructure.text); - - t.is(typeof getTableStructureRO, 'object'); - t.is(typeof getTableStructureRO.structure, 'object'); - t.is(getTableStructureRO.structure.length, 6); - - for (const element of getTableStructureRO.structure) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'column_default'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - t.is(Object.hasOwn(element, 'isExcluded'), true); - t.is(Object.hasOwn(element, 'isSearched'), true); - } - - t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); - - for (const element of getTableStructureRO.primaryColumns) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - } - - for (const element of getTableStructureRO.foreignKeys) { - t.is(Object.hasOwn(element, 'referenced_column_name'), true); - t.is(Object.hasOwn(element, 'referenced_table_name'), true); - t.is(Object.hasOwn(element, 'constraint_name'), true); - t.is(Object.hasOwn(element, 'column_name'), true); - } + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 200); + const getTableStructureRO = JSON.parse(getTableStructure.text); + + t.is(typeof getTableStructureRO, 'object'); + t.is(typeof getTableStructureRO.structure, 'object'); + t.is(getTableStructureRO.structure.length, 6); + + for (const element of getTableStructureRO.structure) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'column_default'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + t.is(Object.hasOwn(element, 'isExcluded'), true); + t.is(Object.hasOwn(element, 'isSearched'), true); + } + + t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); + + for (const element of getTableStructureRO.primaryColumns) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + } + + for (const element of getTableStructureRO.foreignKeys) { + t.is(Object.hasOwn(element, 'referenced_column_name'), true); + t.is(Object.hasOwn(element, 'referenced_table_name'), true); + t.is(Object.hasOwn(element, 'constraint_name'), true); + t.is(Object.hasOwn(element, 'column_name'), true); + } }); test.serial(`${currentTest} should throw an exception whe connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 404); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 404); }); test.serial(`${currentTest} should throw an exception whe connection id passed in request id incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = faker.string.uuid(); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 403); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = faker.string.uuid(); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 403); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest}should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = faker.lorem.words(1); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - - const responseObject = JSON.parse(getTableStructure.text); - t.is(responseObject.message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = faker.lorem.words(1); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + + const responseObject = JSON.parse(getTableStructure.text); + t.is(responseObject.message, Messages.TABLE_NOT_FOUND); }); currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should add row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const fakeId = faker.string.uuid(); - const row = { - "id": fakeId, - "age": 99, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addRowInTableRO = JSON.parse(addRowInTableResponse.text); - t.is(addRowInTableResponse.status, 201); - - t.is(Object.hasOwn(addRowInTableRO, 'row'), true); - t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); - t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 43); - - // check that rows adding was logged - - const getLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getLogsResponse.status, 200); - const getLogsRO = JSON.parse(getLogsResponse.text); - t.is(Object.hasOwn(getLogsRO, 'logs'), true); - t.is(Object.hasOwn(getLogsRO, 'pagination'), true); - t.is(getLogsRO.logs.length > 0, true); - const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); - t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); - t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, fakeId); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const fakeId = faker.string.uuid(); + const row = { + id: fakeId, + age: 99, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addRowInTableRO = JSON.parse(addRowInTableResponse.text); + t.is(addRowInTableResponse.status, 201); + + t.is(Object.hasOwn(addRowInTableRO, 'row'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 43); + + // check that rows adding was logged + + const getLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getLogsResponse.status, 200); + const getLogsRO = JSON.parse(getLogsResponse.text); + t.is(Object.hasOwn(getLogsRO, 'logs'), true); + t.is(Object.hasOwn(getLogsRO, 'pagination'), true); + t.is(getLogsRO.logs.length > 0, true); + const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); + t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); + t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, fakeId); }); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: faker.string.uuid(), - "age": 99, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const fakeConnectionId = ''; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 404); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: faker.string.uuid(), + age: 99, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const fakeConnectionId = ''; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 404); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: faker.string.uuid(), - age: 99, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: faker.string.uuid(), + age: 99, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when row is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.PARAMETER_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.PARAMETER_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: faker.string.uuid(), - age: 99, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.number.int({ min: 1, max: 10000 })}`; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(addRowInTableResponse.text); - t.is(addRowInTableResponse.status, 400); - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: faker.string.uuid(), + age: 99, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.number.int({ min: 1, max: 10000 })}`; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(addRowInTableResponse.text); + t.is(addRowInTableResponse.status, 400); + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); currentTest = 'PUT /table/row/:slug'; test.serial(`${currentTest} should update row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const foundIdForUpdate = insertedSearchedIds[0].id; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${foundIdForUpdate}&age=14`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 200); - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); - t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was updated - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - const updateRowIndex = rows.findIndex((element) => element.id === foundIdForUpdate); - t.is(rows.length, 42); - t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); - t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const foundIdForUpdate = insertedSearchedIds[0].id; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${foundIdForUpdate}&age=14`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 200); + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); + t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was updated + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + const updateRowIndex = rows.findIndex((element) => element.id === foundIdForUpdate); + t.is(rows.length, 42); + t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); + t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const foundIdForUpdate = insertedSearchedIds[0].id; - createConnectionRO.id = ''; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${foundIdForUpdate}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const foundIdForUpdate = insertedSearchedIds[0].id; + createConnectionRO.id = ''; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${foundIdForUpdate}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 404); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - const foundIdForUpdate = insertedSearchedIds[0].id; - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${foundIdForUpdate}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 403); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + const foundIdForUpdate = insertedSearchedIds[0].id; + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${foundIdForUpdate}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 403); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - const foundIdForUpdate = insertedSearchedIds[0].id; - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=&id=${foundIdForUpdate}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + const foundIdForUpdate = insertedSearchedIds[0].id; + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=&id=${foundIdForUpdate}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - const foundIdForUpdate = insertedSearchedIds[0].id; - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${foundIdForUpdate}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + const foundIdForUpdate = insertedSearchedIds[0].id; + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${foundIdForUpdate}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - const foundIdForUpdate = insertedSearchedIds[0].id; - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=${foundIdForUpdate}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + const foundIdForUpdate = insertedSearchedIds[0].id; + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=${foundIdForUpdate}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${faker.string.uuid()}&age=14`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${faker.string.uuid()}&age=14`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/update/:connectionId'; test.serial(`${currentTest} should update multiple rows and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const firstIdToUpdate = insertedSearchedIds[0].id; - const secondIdToUpdate = insertedSearchedIds[1].id; - const requestData = { - primaryKeys: [ - { id: firstIdToUpdate, age: 14 }, - { id: secondIdToUpdate, age: 90 }, - ], - newValues: { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(requestData)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(updateRowInTableResponse.status, 200); - t.is(updateRowInTableRO.success, true); - - // check that the rows were updated - const firstRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${firstIdToUpdate}&age=14`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const firstRow = JSON.parse(firstRowResponse.text); - t.is(firstRowResponse.status, 200); - t.is(firstRow.row[testTableColumnName], fakeName); - t.is(firstRow.row[testTableSecondColumnName], fakeMail); - - const secondRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${secondIdToUpdate}&age=90`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const secondRow = JSON.parse(secondRowResponse.text); - t.is(secondRowResponse.status, 200); - t.is(secondRow.row[testTableColumnName], fakeName); - t.is(secondRow.row[testTableSecondColumnName], fakeMail); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const firstIdToUpdate = insertedSearchedIds[0].id; + const secondIdToUpdate = insertedSearchedIds[1].id; + const requestData = { + primaryKeys: [ + { id: firstIdToUpdate, age: 14 }, + { id: secondIdToUpdate, age: 90 }, + ], + newValues: { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(requestData)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(updateRowInTableResponse.status, 200); + t.is(updateRowInTableRO.success, true); + + // check that the rows were updated + const firstRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${firstIdToUpdate}&age=14`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const firstRow = JSON.parse(firstRowResponse.text); + t.is(firstRowResponse.status, 200); + t.is(firstRow.row[testTableColumnName], fakeName); + t.is(firstRow.row[testTableSecondColumnName], fakeMail); + + const secondRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${secondIdToUpdate}&age=90`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const secondRow = JSON.parse(secondRowResponse.text); + t.is(secondRowResponse.status, 200); + t.is(secondRow.row[testTableColumnName], fakeName); + t.is(secondRow.row[testTableSecondColumnName], fakeMail); }); currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0].id; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}&age=14`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 41); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, true); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0].id; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}&age=14`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 41); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, true); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0].id; - const connectionId = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 404); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0].id; + const connectionId = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 404); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0].id; - const connectionId = faker.string.uuid(); - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 403); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0].id; + const connectionId = faker.string.uuid(); + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 403); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0].id; - const fakeTableName = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0].id; + const fakeTableName = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0].id; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0].id; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0].id; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0].id; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0].id; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0].id; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${faker.string.uuid()}&age=14`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - t.is(deleteRowInTableResponse.status, 400); - t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${faker.string.uuid()}&age=14`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + t.is(deleteRowInTableResponse.status, 400); + t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} found row`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = insertedSearchedIds[0].id; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}&age=14`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 200); - const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); - t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); - t.is(typeof foundRowInTableRO.row, 'object'); - t.is(typeof foundRowInTableRO.structure, 'object'); - t.is(typeof foundRowInTableRO.primaryColumns, 'object'); - t.is(typeof foundRowInTableRO.readonly_fields, 'object'); - t.is(typeof foundRowInTableRO.foreignKeys, 'object'); - t.is(foundRowInTableRO.row.id, idForSearch); - t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); - t.is(Object.keys(foundRowInTableRO.row).length, 6); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = insertedSearchedIds[0].id; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}&age=14`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 200); + const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); + t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); + t.is(typeof foundRowInTableRO.row, 'object'); + t.is(typeof foundRowInTableRO.structure, 'object'); + t.is(typeof foundRowInTableRO.primaryColumns, 'object'); + t.is(typeof foundRowInTableRO.readonly_fields, 'object'); + t.is(typeof foundRowInTableRO.foreignKeys, 'object'); + t.is(foundRowInTableRO.row.id, idForSearch); + t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); + t.is(Object.keys(foundRowInTableRO.row).length, 6); }); test.serial(`${currentTest} should throw an exception, when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const idForSearch = insertedSearchedIds[0].id; - createConnectionRO.id = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const idForSearch = insertedSearchedIds[0].id; + createConnectionRO.id = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 404); }); test.serial( - `${currentTest} should throw an exception, when connection id passed in request is incorrect`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = insertedSearchedIds[0].id; - createConnectionRO.id = faker.string.uuid(); - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 403); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - }, + `${currentTest} should throw an exception, when connection id passed in request is incorrect`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = insertedSearchedIds[0].id; + createConnectionRO.id = faker.string.uuid(); + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 403); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + }, ); test.serial(`${currentTest} should throw an exception, when tableName in not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = insertedSearchedIds[0].id; - const fakeTableName = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = insertedSearchedIds[0].id; + const fakeTableName = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception, when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = insertedSearchedIds[0].id; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const FoundRowRO = JSON.parse(foundRowInTableResponse.text); - t.is(foundRowInTableResponse.status, 400); - t.is(FoundRowRO.message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = insertedSearchedIds[0].id; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const FoundRowRO = JSON.parse(foundRowInTableResponse.text); + t.is(foundRowInTableResponse.status, 400); + t.is(FoundRowRO.message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception, when primary key is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = insertedSearchedIds[0].id; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = insertedSearchedIds[0].id; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = faker.string.uuid(); - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}&age=14`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = faker.string.uuid(); + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}&age=14`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/delete/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const primaryKeysForDeletion: Array> = [ - { - id: insertedSearchedIds[0].id, - age: 14, - }, - { - id: insertedSearchedIds[1].id, - age: 90, - }, - { - id: insertedSearchedIds[2].id, - age: 95, - }, - ]; - const deleteRowsInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) - .send(primaryKeysForDeletion) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowsInTableResponse.status, 200); - const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - // check that lines was deleted - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); - - for (const key of primaryKeysForDeletion) { - t.is( - rows.findIndex((row) => row.id === key.id), - -1, - ); - } - - // check that table deletion was logged - const tableLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(tableLogsResponse.status, 200); - - const tableLogsRO = JSON.parse(tableLogsResponse.text); - t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); - const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); - for (const key of primaryKeysForDeletion) { - t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); - } + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const primaryKeysForDeletion: Array> = [ + { + id: insertedSearchedIds[0].id, + age: 14, + }, + { + id: insertedSearchedIds[1].id, + age: 90, + }, + { + id: insertedSearchedIds[2].id, + age: 95, + }, + ]; + const deleteRowsInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) + .send(primaryKeysForDeletion) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowsInTableResponse.status, 200); + const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + // check that lines was deleted + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); + + for (const key of primaryKeysForDeletion) { + t.is( + rows.findIndex((row) => row.id === key.id), + -1, + ); + } + + // check that table deletion was logged + const tableLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(tableLogsResponse.status, 200); + + const tableLogsRO = JSON.parse(tableLogsResponse.text); + t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); + const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); + for (const key of primaryKeysForDeletion) { + t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); + } }); currentTest = 'DELETE /table/rows/:slug'; test.serial(`${currentTest} should delete rows in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const primaryKeysForDeletion = [ - { - id: insertedSearchedIds[0].id, - age: 14, - }, - { - id: insertedSearchedIds[1].id, - age: 90, - }, - { - id: insertedSearchedIds[2].id, - age: 95, - }, - ]; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) - .send(primaryKeysForDeletion) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - t.is(deleteRowInTableResponse.status, 200); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(getTableRowsResponse.status, 200); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 39); - for (const primaryKey of primaryKeysForDeletion) { - t.is( - rows.findIndex((row) => row.id === primaryKey.id), - -1, - ); - } - - // check that deletion of rows was logged - - const getTableLogs = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const getRowInTableRO = JSON.parse(getTableLogs.text); - const deleteRowsLogs = getRowInTableRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); - t.is(deleteRowsLogs.length, primaryKeysForDeletion.length); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const primaryKeysForDeletion = [ + { + id: insertedSearchedIds[0].id, + age: 14, + }, + { + id: insertedSearchedIds[1].id, + age: 90, + }, + { + id: insertedSearchedIds[2].id, + age: 95, + }, + ]; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) + .send(primaryKeysForDeletion) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + t.is(deleteRowInTableResponse.status, 200); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(getTableRowsResponse.status, 200); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 39); + for (const primaryKey of primaryKeysForDeletion) { + t.is( + rows.findIndex((row) => row.id === primaryKey.id), + -1, + ); + } + + // check that deletion of rows was logged + + const getTableLogs = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getRowInTableRO = JSON.parse(getTableLogs.text); + const deleteRowsLogs = getRowInTableRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); + t.is(deleteRowsLogs.length, primaryKeysForDeletion.length); }); currentTest = 'POST /connection/test'; test.serial(`${currentTest} should test connection and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const testConnectionResponse = await request(app.getHttpServer()) - .post('/connection/test/') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse.status, 201); - const { message } = JSON.parse(testConnectionResponse.text); - t.is(message, 'Successfully connected'); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const testConnectionResponse = await request(app.getHttpServer()) + .post('/connection/test/') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse.status, 201); + const { message } = JSON.parse(testConnectionResponse.text); + t.is(message, 'Successfully connected'); }); test.serial( - `${currentTest} should test connection and return negative result when connection password is incorrect result`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - connectionToTestDB.password = '8764323452888'; - connectionToTestDB.database = 'test_db'; - const testConnectionResponse = await request(app.getHttpServer()) - .post('/connection/test/') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse.status, 201); - const { result } = JSON.parse(testConnectionResponse.text); - t.is(result, false); - }, + `${currentTest} should test connection and return negative result when connection password is incorrect result`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + connectionToTestDB.password = '8764323452888'; + connectionToTestDB.database = 'test_db'; + const testConnectionResponse = await request(app.getHttpServer()) + .post('/connection/test/') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse.status, 201); + const { result } = JSON.parse(testConnectionResponse.text); + t.is(result, false); + }, ); currentTest = 'GET table/csv/:slug'; test.serial(`${currentTest} should return csv file with table data`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - const getTableCsvResponseRO = JSON.parse(getTableCsvResponse.text); - console.info(getTableCsvResponseRO); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + const getTableCsvResponseRO = JSON.parse(getTableCsvResponse.text); + console.info(getTableCsvResponseRO); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); }); test.serial(`${currentTest} should throw exception when csv export is disabled in table settings`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - false, - false, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - t.is(getTableCsvResponse.status, 400); - const { message } = JSON.parse(getTableCsvResponse.text); - t.is(message, Messages.CSV_EXPORT_DISABLED); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + false, + false, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + t.is(getTableCsvResponse.status, 400); + const { message } = JSON.parse(getTableCsvResponse.text); + t.is(message, Messages.CSV_EXPORT_DISABLED); }); test.serial( - `${currentTest} should return csv file with table data with search, with pagination, with sorting, + `${currentTest} should return csv file with table data with search, with pagination, with sorting, with search and pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post( - `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.info(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - }, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post( + `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.info(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + }, ); currentTest = 'POST /table/csv/import/:slug'; test.serial(`${currentTest} should import csv file with table data`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post( - `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.info(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - - function changeIdFieldsValuesInCsvFile(filePatch: string) { - const fileContent = fs.readFileSync(filePatch).toString(); - const rows = fileContent.split('\n'); - const newRows = rows.map((row, index) => { - if (index === 0) { - return row; - } - const columns = row.split(','); - if (columns.length === 1) { - return row; - } - columns[0] = `5${index}`; - return columns.join(','); - }); - return newRows.join('\n'); - } - - const newFileContent = changeIdFieldsValuesInCsvFile(downloadedFilePatch); - fs.writeFileSync(downloadedFilePatch, newFileContent); - - const importCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) - .attach('file', downloadedFilePatch) - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - - const _importCsvRO = JSON.parse(importCsvResponse.text); - t.is(importCsvResponse.status, 201); - - //checking that the lines was added - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(getTableRowsResponse.status, 200); - t.is(getTableRowsRO.rows.length, testEntitiesSeedsCount + 2); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post( + `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.info(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + + function changeIdFieldsValuesInCsvFile(filePatch: string) { + const fileContent = fs.readFileSync(filePatch).toString(); + const rows = fileContent.split('\n'); + const newRows = rows.map((row, index) => { + if (index === 0) { + return row; + } + const columns = row.split(','); + if (columns.length === 1) { + return row; + } + columns[0] = `5${index}`; + return columns.join(','); + }); + return newRows.join('\n'); + } + + const newFileContent = changeIdFieldsValuesInCsvFile(downloadedFilePatch); + fs.writeFileSync(downloadedFilePatch, newFileContent); + + const importCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) + .attach('file', downloadedFilePatch) + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + + const _importCsvRO = JSON.parse(importCsvResponse.text); + t.is(importCsvResponse.status, 201); + + //checking that the lines was added + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(getTableRowsResponse.status, 200); + t.is(getTableRowsRO.rows.length, testEntitiesSeedsCount + 2); }); test.serial(`${currentTest} should throw exception whe csv import is disabled`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - false, - true, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post( - `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.info(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - - function changeIdFieldsValuesInCsvFile(filePatch: string) { - const fileContent = fs.readFileSync(filePatch).toString(); - const rows = fileContent.split('\n'); - const newRows = rows.map((row, index) => { - if (index === 0) { - return row; - } - const columns = row.split(','); - if (columns.length === 1) { - return row; - } - columns[0] = `5${index}`; - return columns.join(','); - }); - return newRows.join('\n'); - } - - const newFileContent = changeIdFieldsValuesInCsvFile(downloadedFilePatch); - fs.writeFileSync(downloadedFilePatch, newFileContent); - - const importCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) - .attach('file', downloadedFilePatch) - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - - t.is(importCsvResponse.status, 400); - - const { message } = JSON.parse(importCsvResponse.text); - t.is(message, Messages.CSV_IMPORT_DISABLED); + const connectionToTestDB = getTestData(mockFactory).cassandraTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + false, + true, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post( + `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.info(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + + function changeIdFieldsValuesInCsvFile(filePatch: string) { + const fileContent = fs.readFileSync(filePatch).toString(); + const rows = fileContent.split('\n'); + const newRows = rows.map((row, index) => { + if (index === 0) { + return row; + } + const columns = row.split(','); + if (columns.length === 1) { + return row; + } + columns[0] = `5${index}`; + return columns.join(','); + }); + return newRows.join('\n'); + } + + const newFileContent = changeIdFieldsValuesInCsvFile(downloadedFilePatch); + fs.writeFileSync(downloadedFilePatch, newFileContent); + + const importCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) + .attach('file', downloadedFilePatch) + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + + t.is(importCsvResponse.status, 400); + + const { message } = JSON.parse(importCsvResponse.text); + t.is(message, Messages.CSV_IMPORT_DISABLED); }); diff --git a/backend/test/ava-tests/saas-tests/table-categories-e2e.test.ts b/backend/test/ava-tests/saas-tests/table-categories-e2e.test.ts index 1104e949e..e0a591018 100644 --- a/backend/test/ava-tests/saas-tests/table-categories-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/table-categories-e2e.test.ts @@ -34,269 +34,269 @@ const _testTables: Array = []; let currentTest; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication() as any; - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication() as any; + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = `PUT /table-categories/:connectionId`; test.serial(`${currentTest} create table categories`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName: firstTesTableName } = await createTestTable(connectionToTestDB); - const { testTableName: secondTesTableName } = await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const categoriesDTO: Array = [ - { - category_name: 'Category 1', - category_color: '#FF5733', - tables: [firstTesTableName], - category_id: 'cat-001', - }, - { - category_name: 'Category 2', - category_color: '#33FF57', - tables: [secondTesTableName], - category_id: 'cat-002', - }, - { - category_name: 'Category 3', - category_color: '#3357FF', - tables: [firstTesTableName, secondTesTableName], - category_id: 'cat-003', - }, - ]; - - const createTableCategoriesResponse = await request(app.getHttpServer()) - .put(`/table-categories/${createConnectionRO.id}`) - .send(categoriesDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createTableCategoriesRO = JSON.parse(createTableCategoriesResponse.text); - - t.is(createTableCategoriesResponse.status, 200); - - t.is(createTableCategoriesRO.length, 3); - t.is(createTableCategoriesRO[0].category_name, 'Category 1'); - t.is(createTableCategoriesRO[0].category_color, '#FF5733'); - t.is(createTableCategoriesRO[0].category_id, 'cat-001'); - t.deepEqual(createTableCategoriesRO[0].tables, [firstTesTableName]); - t.is(createTableCategoriesRO[1].category_name, 'Category 2'); - t.is(createTableCategoriesRO[1].category_color, '#33FF57'); - t.is(createTableCategoriesRO[1].category_id, 'cat-002'); - t.deepEqual(createTableCategoriesRO[1].tables, [secondTesTableName]); - t.is(createTableCategoriesRO[2].category_name, 'Category 3'); - t.is(createTableCategoriesRO[2].category_color, '#3357FF'); - t.is(createTableCategoriesRO[2].category_id, 'cat-003'); - t.deepEqual(createTableCategoriesRO[2].tables, [firstTesTableName, secondTesTableName]); - - // should recreate categories on the new request - const recreateTableCategoriesResponse = await request(app.getHttpServer()) - .put(`/table-categories/${createConnectionRO.id}`) - .send([categoriesDTO[0]]) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const recreateTableCategoriesRO = JSON.parse(recreateTableCategoriesResponse.text); - - t.is(recreateTableCategoriesResponse.status, 200); - - t.is(recreateTableCategoriesRO.length, 1); - t.is(recreateTableCategoriesRO[0].category_name, 'Category 1'); - t.is(recreateTableCategoriesRO[0].category_color, '#FF5733'); - t.is(recreateTableCategoriesRO[0].category_id, 'cat-001'); - t.deepEqual(recreateTableCategoriesRO[0].tables, [firstTesTableName]); - } catch (e) { - console.error(e); - t.fail(); - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName: firstTesTableName } = await createTestTable(connectionToTestDB); + const { testTableName: secondTesTableName } = await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const categoriesDTO: Array = [ + { + category_name: 'Category 1', + category_color: '#FF5733', + tables: [firstTesTableName], + category_id: 'cat-001', + }, + { + category_name: 'Category 2', + category_color: '#33FF57', + tables: [secondTesTableName], + category_id: 'cat-002', + }, + { + category_name: 'Category 3', + category_color: '#3357FF', + tables: [firstTesTableName, secondTesTableName], + category_id: 'cat-003', + }, + ]; + + const createTableCategoriesResponse = await request(app.getHttpServer()) + .put(`/table-categories/${createConnectionRO.id}`) + .send(categoriesDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createTableCategoriesRO = JSON.parse(createTableCategoriesResponse.text); + + t.is(createTableCategoriesResponse.status, 200); + + t.is(createTableCategoriesRO.length, 3); + t.is(createTableCategoriesRO[0].category_name, 'Category 1'); + t.is(createTableCategoriesRO[0].category_color, '#FF5733'); + t.is(createTableCategoriesRO[0].category_id, 'cat-001'); + t.deepEqual(createTableCategoriesRO[0].tables, [firstTesTableName]); + t.is(createTableCategoriesRO[1].category_name, 'Category 2'); + t.is(createTableCategoriesRO[1].category_color, '#33FF57'); + t.is(createTableCategoriesRO[1].category_id, 'cat-002'); + t.deepEqual(createTableCategoriesRO[1].tables, [secondTesTableName]); + t.is(createTableCategoriesRO[2].category_name, 'Category 3'); + t.is(createTableCategoriesRO[2].category_color, '#3357FF'); + t.is(createTableCategoriesRO[2].category_id, 'cat-003'); + t.deepEqual(createTableCategoriesRO[2].tables, [firstTesTableName, secondTesTableName]); + + // should recreate categories on the new request + const recreateTableCategoriesResponse = await request(app.getHttpServer()) + .put(`/table-categories/${createConnectionRO.id}`) + .send([categoriesDTO[0]]) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const recreateTableCategoriesRO = JSON.parse(recreateTableCategoriesResponse.text); + + t.is(recreateTableCategoriesResponse.status, 200); + + t.is(recreateTableCategoriesRO.length, 1); + t.is(recreateTableCategoriesRO[0].category_name, 'Category 1'); + t.is(recreateTableCategoriesRO[0].category_color, '#FF5733'); + t.is(recreateTableCategoriesRO[0].category_id, 'cat-001'); + t.deepEqual(recreateTableCategoriesRO[0].tables, [firstTesTableName]); + } catch (e) { + console.error(e); + t.fail(); + } }); test.serial(`${currentTest} should throw validation exceptions, when table categories dto is invalid`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName: firstTesTableName } = await createTestTable(connectionToTestDB); - const { testTableName: secondTesTableName } = await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const categoriesDTO = [ - { - category_name: 'Category 1', - tables: '[firstTesTableName]', - }, - { - category_name: 'Category 2', - tables: ['non-real-table'], - }, - { - category_name: null, - tables: [firstTesTableName, secondTesTableName], - }, - ]; - - const createTableCategoriesResponse = await request(app.getHttpServer()) - .put(`/table-categories/${createConnectionRO.id}`) - .send(categoriesDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _createTableCategoriesRO = JSON.parse(createTableCategoriesResponse.text); - // console.log('🚀 ~ createTableCategoriesRO:', createTableCategoriesRO); - - t.is(createTableCategoriesResponse.status, 400); - } catch (e) { - console.error(e); - t.fail(); - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName: firstTesTableName } = await createTestTable(connectionToTestDB); + const { testTableName: secondTesTableName } = await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const categoriesDTO = [ + { + category_name: 'Category 1', + tables: '[firstTesTableName]', + }, + { + category_name: 'Category 2', + tables: ['non-real-table'], + }, + { + category_name: null, + tables: [firstTesTableName, secondTesTableName], + }, + ]; + + const createTableCategoriesResponse = await request(app.getHttpServer()) + .put(`/table-categories/${createConnectionRO.id}`) + .send(categoriesDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _createTableCategoriesRO = JSON.parse(createTableCategoriesResponse.text); + // console.log('🚀 ~ createTableCategoriesRO:', createTableCategoriesRO); + + t.is(createTableCategoriesResponse.status, 400); + } catch (e) { + console.error(e); + t.fail(); + } }); currentTest = `GET /table-categories/:connectionId`; test.serial(`${currentTest} find table categories`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName: firstTesTableName } = await createTestTable(connectionToTestDB); - const { testTableName: secondTesTableName } = await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const categoriesDTO: Array = [ - { - category_name: 'Category 1', - category_color: '#FF5733', - tables: [firstTesTableName], - category_id: 'cat-001', - }, - { - category_name: 'Category 2', - category_color: '#33FF57', - tables: [secondTesTableName], - category_id: 'cat-002', - }, - { - category_name: 'Category 3', - category_color: '#3357FF', - tables: [firstTesTableName, secondTesTableName], - category_id: 'cat-003', - }, - ]; - - const createTableCategoriesResponse = await request(app.getHttpServer()) - .put(`/table-categories/${createConnectionRO.id}`) - .send(categoriesDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableCategoriesResponse.status, 200); - - const findTableCategoriesResponse = await request(app.getHttpServer()) - .get(`/table-categories/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const findTableCategoriesRO = JSON.parse(findTableCategoriesResponse.text); - - t.is(findTableCategoriesResponse.status, 200); - - t.is(findTableCategoriesRO.length, 3); - t.is(findTableCategoriesRO[0].category_name, 'Category 1'); - t.is(findTableCategoriesRO[0].category_color, '#FF5733'); - t.is(findTableCategoriesRO[0].category_id, 'cat-001'); - t.deepEqual(findTableCategoriesRO[0].tables, [firstTesTableName]); - t.is(findTableCategoriesRO[1].category_name, 'Category 2'); - t.is(findTableCategoriesRO[1].category_color, '#33FF57'); - t.is(findTableCategoriesRO[1].category_id, 'cat-002'); - t.deepEqual(findTableCategoriesRO[1].tables, [secondTesTableName]); - t.is(findTableCategoriesRO[2].category_name, 'Category 3'); - t.is(findTableCategoriesRO[2].category_color, '#3357FF'); - t.is(findTableCategoriesRO[2].category_id, 'cat-003'); - t.deepEqual(findTableCategoriesRO[2].tables, [firstTesTableName, secondTesTableName]); - - // should recreate categories on the new request - const recreateTableCategoriesResponse = await request(app.getHttpServer()) - .put(`/table-categories/${createConnectionRO.id}`) - .send([categoriesDTO[0]]) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _recreateTableCategoriesRO = JSON.parse(recreateTableCategoriesResponse.text); - - t.is(recreateTableCategoriesResponse.status, 200); - - // get should return updated categories - const getAfterRecreateTableCategoriesResponse = await request(app.getHttpServer()) - .get(`/table-categories/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getAfterRecreateTableCategoriesRO = JSON.parse(getAfterRecreateTableCategoriesResponse.text); - - t.is(getAfterRecreateTableCategoriesResponse.status, 200); - - t.is(getAfterRecreateTableCategoriesRO.length, 1); - t.is(getAfterRecreateTableCategoriesRO[0].category_name, 'Category 1'); - t.is(getAfterRecreateTableCategoriesRO[0].category_color, '#FF5733'); - t.is(getAfterRecreateTableCategoriesRO[0].category_id, 'cat-001'); - t.deepEqual(getAfterRecreateTableCategoriesRO[0].tables, [firstTesTableName]); - } catch (e) { - console.error(e); - t.fail(); - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName: firstTesTableName } = await createTestTable(connectionToTestDB); + const { testTableName: secondTesTableName } = await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const categoriesDTO: Array = [ + { + category_name: 'Category 1', + category_color: '#FF5733', + tables: [firstTesTableName], + category_id: 'cat-001', + }, + { + category_name: 'Category 2', + category_color: '#33FF57', + tables: [secondTesTableName], + category_id: 'cat-002', + }, + { + category_name: 'Category 3', + category_color: '#3357FF', + tables: [firstTesTableName, secondTesTableName], + category_id: 'cat-003', + }, + ]; + + const createTableCategoriesResponse = await request(app.getHttpServer()) + .put(`/table-categories/${createConnectionRO.id}`) + .send(categoriesDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableCategoriesResponse.status, 200); + + const findTableCategoriesResponse = await request(app.getHttpServer()) + .get(`/table-categories/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const findTableCategoriesRO = JSON.parse(findTableCategoriesResponse.text); + + t.is(findTableCategoriesResponse.status, 200); + + t.is(findTableCategoriesRO.length, 3); + t.is(findTableCategoriesRO[0].category_name, 'Category 1'); + t.is(findTableCategoriesRO[0].category_color, '#FF5733'); + t.is(findTableCategoriesRO[0].category_id, 'cat-001'); + t.deepEqual(findTableCategoriesRO[0].tables, [firstTesTableName]); + t.is(findTableCategoriesRO[1].category_name, 'Category 2'); + t.is(findTableCategoriesRO[1].category_color, '#33FF57'); + t.is(findTableCategoriesRO[1].category_id, 'cat-002'); + t.deepEqual(findTableCategoriesRO[1].tables, [secondTesTableName]); + t.is(findTableCategoriesRO[2].category_name, 'Category 3'); + t.is(findTableCategoriesRO[2].category_color, '#3357FF'); + t.is(findTableCategoriesRO[2].category_id, 'cat-003'); + t.deepEqual(findTableCategoriesRO[2].tables, [firstTesTableName, secondTesTableName]); + + // should recreate categories on the new request + const recreateTableCategoriesResponse = await request(app.getHttpServer()) + .put(`/table-categories/${createConnectionRO.id}`) + .send([categoriesDTO[0]]) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _recreateTableCategoriesRO = JSON.parse(recreateTableCategoriesResponse.text); + + t.is(recreateTableCategoriesResponse.status, 200); + + // get should return updated categories + const getAfterRecreateTableCategoriesResponse = await request(app.getHttpServer()) + .get(`/table-categories/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getAfterRecreateTableCategoriesRO = JSON.parse(getAfterRecreateTableCategoriesResponse.text); + + t.is(getAfterRecreateTableCategoriesResponse.status, 200); + + t.is(getAfterRecreateTableCategoriesRO.length, 1); + t.is(getAfterRecreateTableCategoriesRO[0].category_name, 'Category 1'); + t.is(getAfterRecreateTableCategoriesRO[0].category_color, '#FF5733'); + t.is(getAfterRecreateTableCategoriesRO[0].category_id, 'cat-001'); + t.deepEqual(getAfterRecreateTableCategoriesRO[0].tables, [firstTesTableName]); + } catch (e) { + console.error(e); + t.fail(); + } }); diff --git a/backend/test/ava-tests/saas-tests/table-dynamodb-e2e.test.ts b/backend/test/ava-tests/saas-tests/table-dynamodb-e2e.test.ts index deb8202c1..7e6004e81 100644 --- a/backend/test/ava-tests/saas-tests/table-dynamodb-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/table-dynamodb-e2e.test.ts @@ -39,3998 +39,3998 @@ const testTables: Array = []; let currentTest; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication() as any; - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication() as any; + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /connection/tables/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const getTablesRO = JSON.parse(getTablesResponse.text); - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.length > 0, true); - - const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); - - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); - t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); - t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); - t.is(getTablesRO[testTableIndex].table, testTableName); - t.is(getTablesRO[testTableIndex].permissions.visibility, true); - t.is(getTablesRO[testTableIndex].permissions.readonly, false); - t.is(getTablesRO[testTableIndex].permissions.add, true); - t.is(getTablesRO[testTableIndex].permissions.delete, true); - t.is(getTablesRO[testTableIndex].permissions.edit, true); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getTablesRO = JSON.parse(getTablesResponse.text); + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.length > 0, true); + + const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); + + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); + t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); + t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); + t.is(getTablesRO[testTableIndex].table, testTableName); + t.is(getTablesRO[testTableIndex].permissions.visibility, true); + t.is(getTablesRO[testTableIndex].permissions.readonly, false); + t.is(getTablesRO[testTableIndex].permissions.add, true); + t.is(getTablesRO[testTableIndex].permissions.delete, true); + t.is(getTablesRO[testTableIndex].permissions.edit, true); }); test.serial(`${currentTest} should throw an error when connectionId not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = ''; - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = ''; + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connection id is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = faker.string.uuid(); - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 400); - const { message } = JSON.parse(getTablesResponse.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = faker.string.uuid(); + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 400); + const { message } = JSON.parse(getTablesResponse.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); }); currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return rows of selected table without search and without pagination`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(getTableRowsResponse.status, 200); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(Object.hasOwn(getTableRowsRO, 'large_dataset'), true); - t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 11); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(getTableRowsResponse.status, 200); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(Object.hasOwn(getTableRowsRO, 'large_dataset'), true); + t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 11); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); }); test.serial(`${currentTest} should return rows of selected table with search and without pagination`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createTableSettingsResponse.status, 201); - - const searchedDescription = 5; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(getTableRowsResponse.status, 200); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); - t.is(getTableRowsRO.rows[0].id, searchedDescription); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const searchedDescription = 5; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(getTableRowsResponse.status, 200); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); + t.is(getTableRowsRO.rows[0].id, searchedDescription); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); }); test.serial(`${currentTest} should return page of all rows with pagination page=1, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Content-Type', 'application/json') - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 11); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'number'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 11); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'number'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=3, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 11); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'number'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 3); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 11); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'number'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 3); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'number'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'number'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'number'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'number'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by DESC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 11); - // t.is(getTableRowsRO.rows[0].id, 42); - // t.is(getTableRowsRO.rows[1].id, 41); - // t.is(getTableRowsRO.rows[41].id, 1); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 11); + // t.is(getTableRowsRO.rows[0].id, 42); + // t.is(getTableRowsRO.rows[1].id, 41); + // t.is(getTableRowsRO.rows[41].id, 1); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by ASC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - const searchedLastId = 9; - const searchedFirstId = 0; - const searchedSecondId = 1; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 11); - t.is(getTableRowsRO.rows[0].id, searchedFirstId); - t.is(getTableRowsRO.rows[1].id, searchedSecondId); - t.is(getTableRowsRO.rows[41].id, searchedLastId); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + const searchedLastId = 9; + const searchedFirstId = 0; + const searchedSecondId = 1; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 11); + t.is(getTableRowsRO.rows[0].id, searchedFirstId); + t.is(getTableRowsRO.rows[1].id, searchedSecondId); + t.is(getTableRowsRO.rows[41].id, searchedLastId); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and with pagination and with sorting + `${currentTest} without search and with pagination and with sorting should return all found rows with sorting ports by DESC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - const searchedLastId = 8; - - const preSearchedLastId = 9; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 11); - t.is(getTableRowsRO.rows[0].id, preSearchedLastId); - t.is(getTableRowsRO.rows[1].id, searchedLastId); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + const searchedLastId = 8; + + const preSearchedLastId = 9; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 11); + t.is(getTableRowsRO.rows[0].id, preSearchedLastId); + t.is(getTableRowsRO.rows[1].id, searchedLastId); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - const searchedFirstId = 0; - - const preSearchedSecondId = 1; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 11); - t.is(getTableRowsRO.rows[0].id, searchedFirstId); - t.is(getTableRowsRO.rows[1].id, preSearchedSecondId); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + const searchedFirstId = 0; + + const preSearchedSecondId = 1; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 11); + t.is(getTableRowsRO.rows[0].id, searchedFirstId); + t.is(getTableRowsRO.rows[1].id, preSearchedSecondId); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - const searchedFirstId = 6; - - const searchedSecondId = 5; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 11); - t.is(getTableRowsRO.rows[0].id, searchedFirstId); - t.is(getTableRowsRO.rows[1].id, searchedSecondId); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + const searchedFirstId = 6; + + const searchedSecondId = 5; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 11); + t.is(getTableRowsRO.rows[0].id, searchedFirstId); + t.is(getTableRowsRO.rows[1].id, searchedSecondId); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - const searchedFirstId = 37; - - const searchedSecondId = 21; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 11); - t.is(getTableRowsRO.rows[0].id, searchedFirstId); - t.is(getTableRowsRO.rows[1].id, searchedSecondId); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + const searchedFirstId = 37; + + const searchedSecondId = 21; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 11); + t.is(getTableRowsRO.rows[0].id, searchedFirstId); + t.is(getTableRowsRO.rows[1].id, searchedSecondId); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - const searchedFirstId = 0; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); - t.is(getTableRowsRO.rows[0].id, searchedFirstId); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + const searchedFirstId = 0; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); + t.is(getTableRowsRO.rows[0].id, searchedFirstId); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const searchedFirstId = 0; - const searchedSecondId = 21; - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); - t.is(getTableRowsRO.rows[0].id, searchedFirstId); - t.is(getTableRowsRO.rows[1].id, searchedSecondId); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const searchedFirstId = 0; + const searchedSecondId = 21; + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); + t.is(getTableRowsRO.rows[0].id, searchedFirstId); + t.is(getTableRowsRO.rows[1].id, searchedSecondId); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - const searchedFirstId = 37; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); - t.is(getTableRowsRO.rows[0].id, searchedFirstId); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + const searchedFirstId = 37; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); + t.is(getTableRowsRO.rows[0].id, searchedFirstId); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); // todo: rework for other tables after removing old endpoint test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and filtering in body`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'age'; - const fieldvalue = 18; - - const filters = { - [fieldname]: { lt: fieldvalue }, - }; - - const getTableRowsResponse = await request(app.getHttpServer()) - .post( - `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .send({ filters }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); - - const foundId = 0; - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, foundId); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'age'; + const fieldvalue = 18; + + const filters = { + [fieldname]: { lt: fieldvalue }, + }; + + const getTableRowsResponse = await request(app.getHttpServer()) + .post( + `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .send({ filters }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); + + const foundId = 0; + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, foundId); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=10 and DESC sorting and filtering'`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'age'; - const fieldvalue = 18; - - const filters = { - [fieldname]: { lt: fieldvalue }, - }; - - const getTableRowsResponse = await request(app.getHttpServer()) - .post( - `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10`, - ) - .send({ filters }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 201); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); - - const foundId = 0; - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, foundId); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 10); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'age'; + const fieldvalue = 18; + + const filters = { + [fieldname]: { lt: fieldvalue }, + }; + + const getTableRowsResponse = await request(app.getHttpServer()) + .post( + `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10`, + ) + .send({ filters }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 201); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); + + const foundId = 0; + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, foundId); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 10); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and with multi filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'age'; - const fieldGtvalue = 14; - const fieldLtvalue = 95; - - const filters = { - [fieldname]: { gt: fieldGtvalue, lt: fieldLtvalue }, - }; - - const getTableRowsResponse = await request(app.getHttpServer()) - .post( - `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=3`, - ) - .send({ filters }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 201); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); - - const findRowId = 21; - - t.is(getTableRowsRO.rows[0].id, findRowId); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 3); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'age'; + const fieldGtvalue = 14; + const fieldLtvalue = 95; + + const filters = { + [fieldname]: { gt: fieldGtvalue, lt: fieldLtvalue }, + }; + + const getTableRowsResponse = await request(app.getHttpServer()) + .post( + `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=3`, + ) + .send({ filters }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 201); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); + + const findRowId = 21; + + t.is(getTableRowsRO.rows[0].id, findRowId); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 3); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering by id + `${currentTest} with search, with pagination, with sorting and with filtering by id should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and with multi filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const _fieldname = 'age'; - const idFieldName = 'id'; - const idFieldValue = 21; - const _fieldGtvalue = 14; - // const fieldLtvalue = 95; - - const filters = { - // [fieldname]: { gt: fieldGtvalue }, - [idFieldName]: { eq: idFieldValue }, - }; - - const getTableRowsResponse = await request(app.getHttpServer()) - .post(`/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=3`) - .send({ filters }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 201); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - console.log('🚀 ~ getTableRowsRO:', getTableRowsRO.rows); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); - - const findRowId = 21; - - t.is(getTableRowsRO.rows[0].id, findRowId); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 3); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const _fieldname = 'age'; + const idFieldName = 'id'; + const idFieldValue = 21; + const _fieldGtvalue = 14; + // const fieldLtvalue = 95; + + const filters = { + // [fieldname]: { gt: fieldGtvalue }, + [idFieldName]: { eq: idFieldValue }, + }; + + const getTableRowsResponse = await request(app.getHttpServer()) + .post(`/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=3`) + .send({ filters }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 201); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + console.log('🚀 ~ getTableRowsRO:', getTableRowsRO.rows); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 11); + + const findRowId = 21; + + t.is(getTableRowsRO.rows[0].id, findRowId); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 3); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - createConnectionRO.id = ''; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + createConnectionRO.id = ''; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - createConnectionRO.id = faker.string.uuid(); - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 403); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + createConnectionRO.id = faker.string.uuid(); + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 403); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 400); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 400); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = faker.lorem.words(1); - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTablesRO = JSON.parse(getTableRowsResponse.text); - t.is(getTablesRO.rows.length, 2); - t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTablesRO, 'pagination'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = faker.lorem.words(1); + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTablesRO = JSON.parse(getTableRowsResponse.text); + t.is(getTablesRO.rows.length, 2); + t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTablesRO, 'pagination'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 200); - const getTableStructureRO = JSON.parse(getTableStructure.text); - - t.is(typeof getTableStructureRO, 'object'); - t.is(typeof getTableStructureRO.structure, 'object'); - t.is(getTableStructureRO.structure.length, 11); - - for (const element of getTableStructureRO.structure) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'column_default'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - t.is(Object.hasOwn(element, 'isExcluded'), true); - t.is(Object.hasOwn(element, 'isSearched'), true); - } - - t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); - - for (const element of getTableStructureRO.primaryColumns) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - } - - for (const element of getTableStructureRO.foreignKeys) { - t.is(Object.hasOwn(element, 'referenced_column_name'), true); - t.is(Object.hasOwn(element, 'referenced_table_name'), true); - t.is(Object.hasOwn(element, 'constraint_name'), true); - t.is(Object.hasOwn(element, 'column_name'), true); - } + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 200); + const getTableStructureRO = JSON.parse(getTableStructure.text); + + t.is(typeof getTableStructureRO, 'object'); + t.is(typeof getTableStructureRO.structure, 'object'); + t.is(getTableStructureRO.structure.length, 11); + + for (const element of getTableStructureRO.structure) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'column_default'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + t.is(Object.hasOwn(element, 'isExcluded'), true); + t.is(Object.hasOwn(element, 'isSearched'), true); + } + + t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); + + for (const element of getTableStructureRO.primaryColumns) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + } + + for (const element of getTableStructureRO.foreignKeys) { + t.is(Object.hasOwn(element, 'referenced_column_name'), true); + t.is(Object.hasOwn(element, 'referenced_table_name'), true); + t.is(Object.hasOwn(element, 'constraint_name'), true); + t.is(Object.hasOwn(element, 'column_name'), true); + } }); test.serial(`${currentTest} should throw an exception whe connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 404); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 404); }); test.serial(`${currentTest} should throw an exception whe connection id passed in request id incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = faker.string.uuid(); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 403); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = faker.string.uuid(); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 403); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest}should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = faker.lorem.words(1); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = faker.lorem.words(1); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should add row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - binary_set_column: null, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addRowInTableRO = JSON.parse(addRowInTableResponse.text); - t.is(addRowInTableResponse.status, 201); - - t.is(Object.hasOwn(addRowInTableRO, 'row'), true); - t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); - t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 43); - const rowWithAddedId = rows.findIndex((r) => r.id === 999); - t.is(rows[rowWithAddedId][testTableColumnName], row[testTableColumnName]); - t.is(rows[rowWithAddedId][testTableSecondColumnName], row[testTableSecondColumnName]); - - // check that rows adding was logged - - const getLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getLogsResponse.status, 200); - const getLogsRO = JSON.parse(getLogsResponse.text); - t.is(Object.hasOwn(getLogsRO, 'logs'), true); - t.is(Object.hasOwn(getLogsRO, 'pagination'), true); - t.is(getLogsRO.logs.length > 0, true); - const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); - t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + binary_set_column: null, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addRowInTableRO = JSON.parse(addRowInTableResponse.text); + t.is(addRowInTableResponse.status, 201); + + t.is(Object.hasOwn(addRowInTableRO, 'row'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 43); + const rowWithAddedId = rows.findIndex((r) => r.id === 999); + t.is(rows[rowWithAddedId][testTableColumnName], row[testTableColumnName]); + t.is(rows[rowWithAddedId][testTableSecondColumnName], row[testTableSecondColumnName]); + + // check that rows adding was logged + + const getLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getLogsResponse.status, 200); + const getLogsRO = JSON.parse(getLogsResponse.text); + t.is(Object.hasOwn(getLogsRO, 'logs'), true); + t.is(Object.hasOwn(getLogsRO, 'pagination'), true); + t.is(getLogsRO.logs.length > 0, true); + const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); + t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); }); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const fakeConnectionId = ''; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 404); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const fakeConnectionId = ''; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 404); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when row is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.PARAMETER_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.PARAMETER_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.number.int({ min: 1, max: 10000 })}`; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.number.int({ min: 1, max: 10000 })}`; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); currentTest = 'PUT /table/row/:slug'; test.serial(`${currentTest} should update row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const foundIdForUpdate = 1; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${foundIdForUpdate}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(updateRowInTableResponse.status, 200); - - t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); - t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was updated - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - const updateRowIndex = rows.map((row) => row.id).indexOf(foundIdForUpdate); - t.is(rows.length, 42); - t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); - t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const foundIdForUpdate = 1; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${foundIdForUpdate}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(updateRowInTableResponse.status, 200); + + t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); + t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was updated + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + const updateRowIndex = rows.map((row) => row.id).indexOf(foundIdForUpdate); + t.is(rows.length, 42); + t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); + t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = ''; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = ''; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 404); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 403); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 403); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const responseObject = JSON.parse(updateRowInTableResponse.text); - t.is(responseObject.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const responseObject = JSON.parse(updateRowInTableResponse.text); + t.is(responseObject.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/update/:connectionId'; test.serial(`${currentTest} should update multiple rows and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const foundFirstIdForUpdate = '1'; - const foundSecondIdForUpdate = '2'; - const requestData = { - primaryKeys: [{ id: foundFirstIdForUpdate }, { id: foundSecondIdForUpdate }], - newValues: { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(requestData)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(updateRowInTableResponse.status, 200); - t.is(updateRowInTableRO.success, true); - - // check that the rows were updated - const firstRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${foundFirstIdForUpdate}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const firstRow = JSON.parse(firstRowResponse.text); - t.is(firstRowResponse.status, 200); - t.is(firstRow.row[testTableColumnName], fakeName); - t.is(firstRow.row[testTableSecondColumnName], fakeMail); - - const secondRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${foundSecondIdForUpdate}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const secondRow = JSON.parse(secondRowResponse.text); - t.is(secondRowResponse.status, 200); - t.is(secondRow.row[testTableColumnName], fakeName); - t.is(secondRow.row[testTableSecondColumnName], fakeMail); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const foundFirstIdForUpdate = '1'; + const foundSecondIdForUpdate = '2'; + const requestData = { + primaryKeys: [{ id: foundFirstIdForUpdate }, { id: foundSecondIdForUpdate }], + newValues: { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(requestData)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(updateRowInTableResponse.status, 200); + t.is(updateRowInTableRO.success, true); + + // check that the rows were updated + const firstRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${foundFirstIdForUpdate}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const firstRow = JSON.parse(firstRowResponse.text); + t.is(firstRowResponse.status, 200); + t.is(firstRow.row[testTableColumnName], fakeName); + t.is(firstRow.row[testTableSecondColumnName], fakeMail); + + const secondRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${foundSecondIdForUpdate}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const secondRow = JSON.parse(secondRowResponse.text); + t.is(secondRowResponse.status, 200); + t.is(secondRow.row[testTableColumnName], fakeName); + t.is(secondRow.row[testTableSecondColumnName], fakeMail); }); currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 41); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, true); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 41); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, true); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 404); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 404); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = faker.string.uuid(); - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 403); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = faker.string.uuid(); + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 403); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - t.is(deleteRowInTableResponse.status, 400); - t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + t.is(deleteRowInTableResponse.status, 400); + t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} found row`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 21; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 200); - const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); - - t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); - t.is(typeof foundRowInTableRO.row, 'object'); - t.is(typeof foundRowInTableRO.structure, 'object'); - t.is(typeof foundRowInTableRO.primaryColumns, 'object'); - t.is(typeof foundRowInTableRO.readonly_fields, 'object'); - t.is(typeof foundRowInTableRO.foreignKeys, 'object'); - t.is(foundRowInTableRO.row.id, idForSearch); - t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); - t.is(Object.keys(foundRowInTableRO.row).length, 11); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 21; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 200); + const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); + + t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); + t.is(typeof foundRowInTableRO.row, 'object'); + t.is(typeof foundRowInTableRO.structure, 'object'); + t.is(typeof foundRowInTableRO.primaryColumns, 'object'); + t.is(typeof foundRowInTableRO.readonly_fields, 'object'); + t.is(typeof foundRowInTableRO.foreignKeys, 'object'); + t.is(foundRowInTableRO.row.id, idForSearch); + t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); + t.is(Object.keys(foundRowInTableRO.row).length, 11); }); test.serial(`${currentTest} should throw an exception, when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const idForSearch = 1; - createConnectionRO.id = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const idForSearch = 1; + createConnectionRO.id = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 404); }); test.serial( - `${currentTest} should throw an exception, when connection id passed in request is incorrect`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - createConnectionRO.id = faker.string.uuid(); - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 403); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - }, + `${currentTest} should throw an exception, when connection id passed in request is incorrect`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + createConnectionRO.id = faker.string.uuid(); + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 403); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + }, ); test.serial(`${currentTest} should throw an exception, when tableName in not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception, when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception, when primary key is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = '1'; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = '1'; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = '6604197dab8d910eb77783f9'; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _findRowResponse = JSON.parse(foundRowInTableResponse.text); - t.is(foundRowInTableResponse.status, 500); - // t.is(findRowResponse.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = '6604197dab8d910eb77783f9'; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _findRowResponse = JSON.parse(foundRowInTableResponse.text); + t.is(foundRowInTableResponse.status, 500); + // t.is(findRowResponse.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/delete/:slug'; test.serial(`${currentTest} should delete rows in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const primaryKeysForDeletion: Array> = [ - { - id: 1, - }, - { - id: 2, - }, - { - id: 31, - }, - ]; - const deleteRowsInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) - .send(primaryKeysForDeletion) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowsInTableResponse.status, 200); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - // check that lines was deleted - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); - - for (const key of primaryKeysForDeletion) { - t.is( - rows.findIndex((row) => row.id === key.id), - -1, - ); - } - - // check that table deletaion was logged - const tableLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(tableLogsResponse.status, 200); - - const tableLogsRO = JSON.parse(tableLogsResponse.text); - t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); - const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); - for (const key of primaryKeysForDeletion) { - t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); - } + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const primaryKeysForDeletion: Array> = [ + { + id: 1, + }, + { + id: 2, + }, + { + id: 31, + }, + ]; + const deleteRowsInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) + .send(primaryKeysForDeletion) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowsInTableResponse.status, 200); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + // check that lines was deleted + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); + + for (const key of primaryKeysForDeletion) { + t.is( + rows.findIndex((row) => row.id === key.id), + -1, + ); + } + + // check that table deletaion was logged + const tableLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(tableLogsResponse.status, 200); + + const tableLogsRO = JSON.parse(tableLogsResponse.text); + t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); + const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); + for (const key of primaryKeysForDeletion) { + t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); + } }); currentTest = 'POST /connection/test'; test.serial(`${currentTest} should test connection and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const testConnectionResponse = await request(app.getHttpServer()) - .post('/connection/test/') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse.status, 201); - const { message } = JSON.parse(testConnectionResponse.text); - t.is(message, 'Successfully connected'); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const testConnectionResponse = await request(app.getHttpServer()) + .post('/connection/test/') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse.status, 201); + const { message } = JSON.parse(testConnectionResponse.text); + t.is(message, 'Successfully connected'); }); currentTest = 'GET table/csv/:slug'; test.serial(`${currentTest} should return csv file with table data`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); }); test.serial( - `${currentTest} should return csv file with table data with search, with pagination, with sorting, + `${currentTest} should return csv file with table data with search, with pagination, with sorting, with search and pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post( - `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - }, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post( + `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + }, ); currentTest = 'POST /table/csv/import/:slug'; //todo rework after adding object datatypes processing test.skip(`${currentTest} should import csv file with table data`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post( - `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - - function changeIdFieldsValuesInCsvFile(filePath: string): string { - // eslint-disable-next-line security/detect-non-literal-fs-filename - const fileContent = fs.readFileSync(filePath).toString(); - const rows = fileContent.split('\n'); - - const header = rows[0].split(','); - const idIndex = header.indexOf('id'); - - if (idIndex === -1) { - throw new Error("The 'id' column was not found in the CSV file."); - } - - // Process each row and change the 'id' field - const newRows = rows.map((row, index) => { - if (index === 0) { - return row; // Skip the header row - } - const columns = row.split(','); - if (columns.length <= idIndex) { - return row; // Skip rows that don't have enough columns - } - columns[idIndex] = `5${index}`; - return columns.join(','); - }); - - return newRows.join('\n'); - } - - const newFileContent = changeIdFieldsValuesInCsvFile(downloadedFilePatch); - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, newFileContent); - - const importCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) - .attach('file', downloadedFilePatch) - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - - t.is(importCsvResponse.status, 201); - - //checking that the lines was added - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(getTableRowsResponse.status, 200); - t.is(getTableRowsRO.rows.length, testEntitiesSeedsCount + 2); + const connectionToTestDB = getTestData(mockFactory).dynamoDBConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post( + `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + + function changeIdFieldsValuesInCsvFile(filePath: string): string { + // eslint-disable-next-line security/detect-non-literal-fs-filename + const fileContent = fs.readFileSync(filePath).toString(); + const rows = fileContent.split('\n'); + + const header = rows[0].split(','); + const idIndex = header.indexOf('id'); + + if (idIndex === -1) { + throw new Error("The 'id' column was not found in the CSV file."); + } + + // Process each row and change the 'id' field + const newRows = rows.map((row, index) => { + if (index === 0) { + return row; // Skip the header row + } + const columns = row.split(','); + if (columns.length <= idIndex) { + return row; // Skip rows that don't have enough columns + } + columns[idIndex] = `5${index}`; + return columns.join(','); + }); + + return newRows.join('\n'); + } + + const newFileContent = changeIdFieldsValuesInCsvFile(downloadedFilePatch); + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, newFileContent); + + const importCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) + .attach('file', downloadedFilePatch) + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + + t.is(importCsvResponse.status, 201); + + //checking that the lines was added + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(getTableRowsResponse.status, 200); + t.is(getTableRowsRO.rows.length, testEntitiesSeedsCount + 2); }); diff --git a/backend/test/ava-tests/saas-tests/table-elasticsearch-e2e.test.ts b/backend/test/ava-tests/saas-tests/table-elasticsearch-e2e.test.ts index 1020e0048..82e721e21 100644 --- a/backend/test/ava-tests/saas-tests/table-elasticsearch-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/table-elasticsearch-e2e.test.ts @@ -39,3943 +39,3943 @@ const testTables: Array = []; let currentTest; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication() as any; - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication() as any; + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /connection/tables/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTablesRO = JSON.parse(getTablesResponse.text); - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.length > 0, true); - - const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); - - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); - t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); - t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); - t.is(getTablesRO[testTableIndex].table, testTableName); - t.is(getTablesRO[testTableIndex].permissions.visibility, true); - t.is(getTablesRO[testTableIndex].permissions.readonly, false); - t.is(getTablesRO[testTableIndex].permissions.add, true); - t.is(getTablesRO[testTableIndex].permissions.delete, true); - t.is(getTablesRO[testTableIndex].permissions.edit, true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTablesRO = JSON.parse(getTablesResponse.text); + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.length > 0, true); + + const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); + + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); + t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); + t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); + t.is(getTablesRO[testTableIndex].table, testTableName); + t.is(getTablesRO[testTableIndex].permissions.visibility, true); + t.is(getTablesRO[testTableIndex].permissions.readonly, false); + t.is(getTablesRO[testTableIndex].permissions.add, true); + t.is(getTablesRO[testTableIndex].permissions.delete, true); + t.is(getTablesRO[testTableIndex].permissions.edit, true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connectionId not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = ''; - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = ''; + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connection id is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = faker.string.uuid(); - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 400); - const { message } = JSON.parse(getTablesResponse.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = faker.string.uuid(); + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 400); + const { message } = JSON.parse(getTablesResponse.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return rows of selected table without search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(getTableRowsResponse.status, 200); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(Object.hasOwn(getTableRowsRO, 'large_dataset'), true); - t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(Object.hasOwn(getTableRowsRO.rows[0], '_id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(getTableRowsResponse.status, 200); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(Object.hasOwn(getTableRowsRO, 'large_dataset'), true); + t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(Object.hasOwn(getTableRowsRO.rows[0], '_id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return rows of selected table with search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createTableSettingsResponse.status, 201); - - const searchedDescription = 'Vasia'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(getTableRowsResponse.status, 200); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0][testTableColumnName], searchedDescription); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const searchedDescription = 'Vasia'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(getTableRowsResponse.status, 200); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0][testTableColumnName], searchedDescription); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=1, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['age'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Content-Type', 'application/json') - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(Object.hasOwn(getTableRowsRO.rows[0], '_id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, '_id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['age'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(Object.hasOwn(getTableRowsRO.rows[0], '_id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, '_id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=3, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['age'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(Object.hasOwn(getTableRowsRO.rows[0], '_id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, '_id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 3); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['age'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(Object.hasOwn(getTableRowsRO.rows[0], '_id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, '_id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 3); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, '_id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, '_id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, '_id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, '_id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by DESC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - // t.is(getTableRowsRO.rows[0]._id, 42); - // t.is(getTableRowsRO.rows[1]._id, 41); - // t.is(getTableRowsRO.rows[41]._id, 1); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + // t.is(getTableRowsRO.rows[0]._id, 42); + // t.is(getTableRowsRO.rows[1]._id, 41); + // t.is(getTableRowsRO.rows[41]._id, 1); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting AGE by ASC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.ASC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - - for (let i = 1; i < getTableRowsRO.rows.length; i++) { - t.true(getTableRowsRO.rows[i - 1].age <= getTableRowsRO.rows[i].age); - } - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.ASC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + + for (let i = 1; i < getTableRowsRO.rows.length; i++) { + t.true(getTableRowsRO.rows[i - 1].age <= getTableRowsRO.rows[i].age); + } + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and with pagination and with sorting + `${currentTest} without search and with pagination and with sorting should return all found rows with sorting age by DESC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - - t.true(getTableRowsRO.rows[0].age >= getTableRowsRO.rows[1].age); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + + t.true(getTableRowsRO.rows[0].age >= getTableRowsRO.rows[1].age); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting age by ASC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - - t.true(getTableRowsRO.rows[0].age <= getTableRowsRO.rows[1].age); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting age by ASC and with pagination page=1, perPage=2`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + + t.true(getTableRowsRO.rows[0].age <= getTableRowsRO.rows[1].age); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - - for (let i = 1; i < getTableRowsRO.rows.length; i++) { - t.true(getTableRowsRO.rows[i - 1].age >= getTableRowsRO.rows[i].age); - } - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + + for (let i = 1; i < getTableRowsRO.rows.length; i++) { + t.true(getTableRowsRO.rows[i - 1].age >= getTableRowsRO.rows[i].age); + } + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - for (let i = 1; i < getTableRowsRO.rows.length; i++) { - t.true(getTableRowsRO.rows[i - 1].age >= getTableRowsRO.rows[i].age); - } - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + for (let i = 1; i < getTableRowsRO.rows.length; i++) { + t.true(getTableRowsRO.rows[i - 1].age >= getTableRowsRO.rows[i].age); + } + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and ASC age sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(getTableRowsResponse.status, 200); - - const searchedFirstId = insertedSearchedIds.find((id) => id.number === 0)._id; - const searchedSecondId = insertedSearchedIds.find((id) => id.number === 21)._id; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0]._id, searchedFirstId); - t.is(getTableRowsRO.rows[1]._id, searchedSecondId); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(getTableRowsResponse.status, 200); + + const searchedFirstId = insertedSearchedIds.find((id) => id.number === 0)._id; + const searchedSecondId = insertedSearchedIds.find((id) => id.number === 21)._id; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0]._id, searchedFirstId); + t.is(getTableRowsRO.rows[1]._id, searchedSecondId); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - const searchedFirstId = insertedSearchedIds.find((id) => id.number === 37)._id; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0]._id, searchedFirstId); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + const searchedFirstId = insertedSearchedIds.find((id) => id.number === 37)._id; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0]._id, searchedFirstId); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); // todo: rework for other tables after removing old endpoint test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and filtering in body`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'age'; - const fieldvalue = 18; - - const filters = { - [fieldname]: { lt: fieldvalue }, - }; - - const getTableRowsResponse = await request(app.getHttpServer()) - .post( - `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .send({ filters }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - - const foundId = insertedSearchedIds.find((id) => id.number === 0)._id; - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0]._id, foundId); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'age'; + const fieldvalue = 18; + + const filters = { + [fieldname]: { lt: fieldvalue }, + }; + + const getTableRowsResponse = await request(app.getHttpServer()) + .post( + `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .send({ filters }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + + const foundId = insertedSearchedIds.find((id) => id.number === 0)._id; + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0]._id, foundId); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=10 and DESC sorting and filtering'`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'age'; - const fieldvalue = 18; - - const filters = { - [fieldname]: { lt: fieldvalue }, - }; - - const getTableRowsResponse = await request(app.getHttpServer()) - .post( - `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10`, - ) - .send({ filters }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 201); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - - const foundId = insertedSearchedIds.find((id) => id.number === 0)._id; - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0]._id, foundId); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 10); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'age'; + const fieldvalue = 18; + + const filters = { + [fieldname]: { lt: fieldvalue }, + }; + + const getTableRowsResponse = await request(app.getHttpServer()) + .post( + `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10`, + ) + .send({ filters }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 201); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + + const foundId = insertedSearchedIds.find((id) => id.number === 0)._id; + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0]._id, foundId); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 10); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and with multi filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'age'; - const fieldGtvalue = 14; - const fieldLtvalue = 95; - - const filters = { - [fieldname]: { lt: fieldLtvalue, gt: fieldGtvalue }, - }; - - const getTableRowsResponse = await request(app.getHttpServer()) - .post( - `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=3`, - ) - .send({ filters }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 201); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - - const findRowId = insertedSearchedIds.find((id) => id.number === 21)._id; - - t.is(getTableRowsRO.rows[0]._id, findRowId); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 3); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'age'; + const fieldGtvalue = 14; + const fieldLtvalue = 95; + + const filters = { + [fieldname]: { lt: fieldLtvalue, gt: fieldGtvalue }, + }; + + const getTableRowsResponse = await request(app.getHttpServer()) + .post( + `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=3`, + ) + .send({ filters }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 201); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + + const findRowId = insertedSearchedIds.find((id) => id.number === 21)._id; + + t.is(getTableRowsRO.rows[0]._id, findRowId); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 3); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = '_id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - createConnectionRO.id = ''; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = '_id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + createConnectionRO.id = ''; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = '_id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - createConnectionRO.id = faker.string.uuid(); - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 403); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = '_id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + createConnectionRO.id = faker.string.uuid(); + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 403); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = '_id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 400); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = '_id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 400); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = faker.lorem.words(1); - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTablesRO = JSON.parse(getTableRowsResponse.text); - t.is(getTablesRO.rows.length, 2); - t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTablesRO, 'pagination'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = faker.lorem.words(1); + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTablesRO = JSON.parse(getTableRowsResponse.text); + t.is(getTablesRO.rows.length, 2); + t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTablesRO, 'pagination'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 200); - const getTableStructureRO = JSON.parse(getTableStructure.text); - - t.is(typeof getTableStructureRO, 'object'); - t.is(typeof getTableStructureRO.structure, 'object'); - t.is(getTableStructureRO.structure.length, 6); - - for (const element of getTableStructureRO.structure) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'column_default'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - t.is(Object.hasOwn(element, 'isExcluded'), true); - t.is(Object.hasOwn(element, 'isSearched'), true); - } - - t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); - - for (const element of getTableStructureRO.primaryColumns) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - } - - for (const element of getTableStructureRO.foreignKeys) { - t.is(Object.hasOwn(element, 'referenced_column_name'), true); - t.is(Object.hasOwn(element, 'referenced_table_name'), true); - t.is(Object.hasOwn(element, 'constraint_name'), true); - t.is(Object.hasOwn(element, 'column_name'), true); - } + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 200); + const getTableStructureRO = JSON.parse(getTableStructure.text); + + t.is(typeof getTableStructureRO, 'object'); + t.is(typeof getTableStructureRO.structure, 'object'); + t.is(getTableStructureRO.structure.length, 6); + + for (const element of getTableStructureRO.structure) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'column_default'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + t.is(Object.hasOwn(element, 'isExcluded'), true); + t.is(Object.hasOwn(element, 'isSearched'), true); + } + + t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); + + for (const element of getTableStructureRO.primaryColumns) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + } + + for (const element of getTableStructureRO.foreignKeys) { + t.is(Object.hasOwn(element, 'referenced_column_name'), true); + t.is(Object.hasOwn(element, 'referenced_table_name'), true); + t.is(Object.hasOwn(element, 'constraint_name'), true); + t.is(Object.hasOwn(element, 'column_name'), true); + } }); test.serial(`${currentTest} should throw an exception whe connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 404); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 404); }); test.serial(`${currentTest} should throw an exception whe connection id passed in request id incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = faker.string.uuid(); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 403); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = faker.string.uuid(); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 403); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest}should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = faker.lorem.words(1); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = faker.lorem.words(1); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should add row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addRowInTableRO = JSON.parse(addRowInTableResponse.text); - t.is(addRowInTableResponse.status, 201); - - t.is(Object.hasOwn(addRowInTableRO, 'row'), true); - t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); - t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 43); - t.is(rows[42][testTableColumnName], row[testTableColumnName]); - t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); - - // check that rows adding was logged - - const getLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getLogsResponse.status, 200); - const getLogsRO = JSON.parse(getLogsResponse.text); - t.is(Object.hasOwn(getLogsRO, 'logs'), true); - t.is(Object.hasOwn(getLogsRO, 'pagination'), true); - t.is(getLogsRO.logs.length > 0, true); - const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); - t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, '_id'), true); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addRowInTableRO = JSON.parse(addRowInTableResponse.text); + t.is(addRowInTableResponse.status, 201); + + t.is(Object.hasOwn(addRowInTableRO, 'row'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 43); + t.is(rows[42][testTableColumnName], row[testTableColumnName]); + t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); + + // check that rows adding was logged + + const getLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getLogsResponse.status, 200); + const getLogsRO = JSON.parse(getLogsResponse.text); + t.is(Object.hasOwn(getLogsRO, 'logs'), true); + t.is(Object.hasOwn(getLogsRO, 'pagination'), true); + t.is(getLogsRO.logs.length > 0, true); + const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); + t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, '_id'), true); }); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - _id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const fakeConnectionId = ''; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 404); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + _id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const fakeConnectionId = ''; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 404); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - _id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + _id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when row is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.PARAMETER_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.PARAMETER_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - _id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.number.int({ min: 1, max: 10000 })}`; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + _id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.number.int({ min: 1, max: 10000 })}`; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); currentTest = 'PUT /table/row/:slug'; test.serial(`${currentTest} should update row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const foundIdForUpdate = insertedSearchedIds[0]._id; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${foundIdForUpdate}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 200); - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); - t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was updated - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - const updateRowIndex = rows.map((row) => row._id).indexOf(foundIdForUpdate); - t.is(rows.length, 42); - t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); - t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const foundIdForUpdate = insertedSearchedIds[0]._id; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${foundIdForUpdate}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 200); + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); + t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was updated + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + const updateRowIndex = rows.map((row) => row._id).indexOf(foundIdForUpdate); + t.is(rows.length, 42); + t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); + t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = ''; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = ''; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 404); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 403); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 403); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=&_id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=&_id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=100000000`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const responseObject = JSON.parse(updateRowInTableResponse.text); - t.is(responseObject.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=100000000`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const responseObject = JSON.parse(updateRowInTableResponse.text); + t.is(responseObject.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/update/:connectionId'; test.serial(`${currentTest} should update multiple rows and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const foundFirstIdForUpdate = insertedSearchedIds[0]._id; - const foundSecondIdForUpdate = insertedSearchedIds[1]._id; - const requestData = { - primaryKeys: [{ _id: foundFirstIdForUpdate }, { _id: foundSecondIdForUpdate }], - newValues: { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(requestData)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(updateRowInTableResponse.status, 200); - t.is(updateRowInTableRO.success, true); - - // check that the rows were updated - const firstRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${foundFirstIdForUpdate}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const firstRow = JSON.parse(firstRowResponse.text); - t.is(firstRowResponse.status, 200); - t.is(firstRow.row[testTableColumnName], fakeName); - t.is(firstRow.row[testTableSecondColumnName], fakeMail); - - const secondRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${foundSecondIdForUpdate}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const secondRow = JSON.parse(secondRowResponse.text); - t.is(secondRowResponse.status, 200); - t.is(secondRow.row[testTableColumnName], fakeName); - t.is(secondRow.row[testTableSecondColumnName], fakeMail); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const foundFirstIdForUpdate = insertedSearchedIds[0]._id; + const foundSecondIdForUpdate = insertedSearchedIds[1]._id; + const requestData = { + primaryKeys: [{ _id: foundFirstIdForUpdate }, { _id: foundSecondIdForUpdate }], + newValues: { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(requestData)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(updateRowInTableResponse.status, 200); + t.is(updateRowInTableRO.success, true); + + // check that the rows were updated + const firstRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${foundFirstIdForUpdate}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const firstRow = JSON.parse(firstRowResponse.text); + t.is(firstRowResponse.status, 200); + t.is(firstRow.row[testTableColumnName], fakeName); + t.is(firstRow.row[testTableSecondColumnName], fakeMail); + + const secondRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${foundSecondIdForUpdate}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const secondRow = JSON.parse(secondRowResponse.text); + t.is(secondRowResponse.status, 200); + t.is(secondRow.row[testTableColumnName], fakeName); + t.is(secondRow.row[testTableSecondColumnName], fakeMail); }); currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0]._id; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 41); - const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, true); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0]._id; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 41); + const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, true); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0]._id; - const connectionId = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&_id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 404); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0]._id; + const connectionId = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&_id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 404); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0]._id; - const connectionId = faker.string.uuid(); - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&_id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 403); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0]._id; + const connectionId = faker.string.uuid(); + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&_id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 403); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0]._id; - const fakeTableName = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0]._id; + const fakeTableName = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0]._id; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0]._id; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0]._id; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0]._id; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0]._id; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0]._id; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=100000`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - t.is(deleteRowInTableResponse.status, 400); - t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=100000`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + t.is(deleteRowInTableResponse.status, 400); + t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} found row`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const idForSearch = insertedSearchedIds[0]._id; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); - t.is(foundRowInTableResponse.status, 200); - t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); - t.is(typeof foundRowInTableRO.row, 'object'); - t.is(typeof foundRowInTableRO.structure, 'object'); - t.is(typeof foundRowInTableRO.primaryColumns, 'object'); - t.is(typeof foundRowInTableRO.readonly_fields, 'object'); - t.is(typeof foundRowInTableRO.foreignKeys, 'object'); - t.is(foundRowInTableRO.row._id, idForSearch); - t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); - t.is(Object.keys(foundRowInTableRO.row).length, 6); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const idForSearch = insertedSearchedIds[0]._id; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); + t.is(foundRowInTableResponse.status, 200); + t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); + t.is(typeof foundRowInTableRO.row, 'object'); + t.is(typeof foundRowInTableRO.structure, 'object'); + t.is(typeof foundRowInTableRO.primaryColumns, 'object'); + t.is(typeof foundRowInTableRO.readonly_fields, 'object'); + t.is(typeof foundRowInTableRO.foreignKeys, 'object'); + t.is(foundRowInTableRO.row._id, idForSearch); + t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); + t.is(Object.keys(foundRowInTableRO.row).length, 6); }); test.serial(`${currentTest} should throw an exception, when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const idForSearch = 1; - createConnectionRO.id = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const idForSearch = 1; + createConnectionRO.id = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 404); }); test.serial( - `${currentTest} should throw an exception, when connection id passed in request is incorrect`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - createConnectionRO.id = faker.string.uuid(); - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 403); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - }, + `${currentTest} should throw an exception, when connection id passed in request is incorrect`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + createConnectionRO.id = faker.string.uuid(); + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 403); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + }, ); test.serial(`${currentTest} should throw an exception, when tableName in not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception, when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception, when primary key is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = insertedSearchedIds[0]._id; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = insertedSearchedIds[0]._id; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = '6604197dab8d910eb77783f9'; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const findRowResponse = JSON.parse(foundRowInTableResponse.text); - t.is(findRowResponse.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = '6604197dab8d910eb77783f9'; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const findRowResponse = JSON.parse(foundRowInTableResponse.text); + t.is(findRowResponse.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/delete/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const primaryKeysForDeletion: Array> = [ - { - _id: insertedSearchedIds[0]._id, - }, - { - _id: insertedSearchedIds[9]._id, - }, - { - _id: insertedSearchedIds[31]._id, - }, - ]; - const deleteRowsInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) - .send(primaryKeysForDeletion) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowsInTableResponse.status, 200); - const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - // check that lines was deleted - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); - - for (const key of primaryKeysForDeletion) { - t.is( - rows.findIndex((row) => row._id === key._id), - -1, - ); - } - - // check that table deletaion was logged - const tableLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(tableLogsResponse.status, 200); - - const tableLogsRO = JSON.parse(tableLogsResponse.text); - t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); - const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); - for (const key of primaryKeysForDeletion) { - t.is(onlyDeleteLogs.findIndex((log) => log.received_data._id === key._id) >= 0, true); - } + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const primaryKeysForDeletion: Array> = [ + { + _id: insertedSearchedIds[0]._id, + }, + { + _id: insertedSearchedIds[9]._id, + }, + { + _id: insertedSearchedIds[31]._id, + }, + ]; + const deleteRowsInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) + .send(primaryKeysForDeletion) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowsInTableResponse.status, 200); + const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + // check that lines was deleted + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); + + for (const key of primaryKeysForDeletion) { + t.is( + rows.findIndex((row) => row._id === key._id), + -1, + ); + } + + // check that table deletaion was logged + const tableLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(tableLogsResponse.status, 200); + + const tableLogsRO = JSON.parse(tableLogsResponse.text); + t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); + const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); + for (const key of primaryKeysForDeletion) { + t.is(onlyDeleteLogs.findIndex((log) => log.received_data._id === key._id) >= 0, true); + } }); currentTest = 'DELETE /table/rows/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const primaryKeysForDeletion = [ - { - _id: insertedSearchedIds[0]._id, - }, - { - _id: insertedSearchedIds[9]._id, - }, - { - _id: insertedSearchedIds[31]._id, - }, - ]; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) - .send(primaryKeysForDeletion) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const _deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(getTableRowsResponse.status, 200); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 39); - for (const primaryKey of primaryKeysForDeletion) { - t.is( - rows.findIndex((row) => row._id === primaryKey._id), - -1, - ); - } + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const primaryKeysForDeletion = [ + { + _id: insertedSearchedIds[0]._id, + }, + { + _id: insertedSearchedIds[9]._id, + }, + { + _id: insertedSearchedIds[31]._id, + }, + ]; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) + .send(primaryKeysForDeletion) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const _deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(getTableRowsResponse.status, 200); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 39); + for (const primaryKey of primaryKeysForDeletion) { + t.is( + rows.findIndex((row) => row._id === primaryKey._id), + -1, + ); + } }); test.serial(`${currentTest} should test connection and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const testConnectionResponse = await request(app.getHttpServer()) - .post('/connection/test/') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse.status, 201); - const { message } = JSON.parse(testConnectionResponse.text); - t.is(message, 'Successfully connected'); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const testConnectionResponse = await request(app.getHttpServer()) + .post('/connection/test/') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse.status, 201); + const { message } = JSON.parse(testConnectionResponse.text); + t.is(message, 'Successfully connected'); }); currentTest = 'GET table/csv/:slug'; test.serial(`${currentTest} should return csv file with table data`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); }); test.serial( - `${currentTest} should return csv file with table data with search, with pagination, with sorting, + `${currentTest} should return csv file with table data with search, with pagination, with sorting, with search and pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post( - `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - }, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post( + `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + }, ); currentTest = 'POST /table/csv/import/:slug'; test.serial(`${currentTest} should import csv file with table data`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'age', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post( - `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - - function deleteIdColumnsInCSVFile(filePatch: string) { - // eslint-disable-next-line security/detect-non-literal-fs-filename - const fileContent = fs.readFileSync(filePatch).toString(); - const rows = fileContent.split('\n'); - const idColumnIndex = rows[0].split(',').indexOf('_id'); - const newRows = rows.map((row) => { - const columns = row.split(','); - if (columns.length === 1) { - return row; - } - if (idColumnIndex >= 0) { - columns.splice(idColumnIndex, 1); - } - return columns.join(','); - }); - return newRows.join('\n'); - } - - const newFileContent = deleteIdColumnsInCSVFile(downloadedFilePatch); - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, newFileContent); - - const importCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) - .attach('file', downloadedFilePatch) - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - - t.is(importCsvResponse.status, 201); - - //checking that the lines was added - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(getTableRowsResponse.status, 200); - t.is(getTableRowsRO.rows.length, testEntitiesSeedsCount + 2); + const connectionToTestDB = getTestData(mockFactory).elasticsearchTestConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'age', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post( + `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + + function deleteIdColumnsInCSVFile(filePatch: string) { + // eslint-disable-next-line security/detect-non-literal-fs-filename + const fileContent = fs.readFileSync(filePatch).toString(); + const rows = fileContent.split('\n'); + const idColumnIndex = rows[0].split(',').indexOf('_id'); + const newRows = rows.map((row) => { + const columns = row.split(','); + if (columns.length === 1) { + return row; + } + if (idColumnIndex >= 0) { + columns.splice(idColumnIndex, 1); + } + return columns.join(','); + }); + return newRows.join('\n'); + } + + const newFileContent = deleteIdColumnsInCSVFile(downloadedFilePatch); + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, newFileContent); + + const importCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) + .attach('file', downloadedFilePatch) + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + + t.is(importCsvResponse.status, 201); + + //checking that the lines was added + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(getTableRowsResponse.status, 200); + t.is(getTableRowsRO.rows.length, testEntitiesSeedsCount + 2); }); diff --git a/backend/test/ava-tests/saas-tests/table-filters-e2e-test.ts b/backend/test/ava-tests/saas-tests/table-filters-e2e-test.ts index 0a862096a..72785e431 100644 --- a/backend/test/ava-tests/saas-tests/table-filters-e2e-test.ts +++ b/backend/test/ava-tests/saas-tests/table-filters-e2e-test.ts @@ -34,661 +34,661 @@ const testTables: Array = []; let currentTest; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication() as any; - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication() as any; + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = `POST /table-filters/:connectionId`; test.serial(`${currentTest} create table filters`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '45'; - - const filters = { - [fieldname]: { lt: fieldvalue }, - }; - - const filtersDTO = { - name: 'Test filter', - filters: filters, - }; - - const createTableFiltersResponse = await request(app.getHttpServer()) - .post(`/table-filters/${createConnectionRO.id}/?tableName=${testTableName}`) - .send({ ...filtersDTO }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createTableFiltersRO = JSON.parse(createTableFiltersResponse.text); - - t.is(createTableFiltersResponse.status, 201); - t.is(Object.hasOwn(createTableFiltersRO, 'id'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'name'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'filters'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'dynamic_column'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'createdAt'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'updatedAt'), true); - t.is(createTableFiltersRO.name, filtersDTO.name); - t.deepEqual(createTableFiltersRO.filters, filtersDTO.filters); - } catch (e) { - console.error(e); - t.fail(); - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '45'; + + const filters = { + [fieldname]: { lt: fieldvalue }, + }; + + const filtersDTO = { + name: 'Test filter', + filters: filters, + }; + + const createTableFiltersResponse = await request(app.getHttpServer()) + .post(`/table-filters/${createConnectionRO.id}/?tableName=${testTableName}`) + .send({ ...filtersDTO }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createTableFiltersRO = JSON.parse(createTableFiltersResponse.text); + + t.is(createTableFiltersResponse.status, 201); + t.is(Object.hasOwn(createTableFiltersRO, 'id'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'name'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'filters'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'dynamic_column'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'createdAt'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'updatedAt'), true); + t.is(createTableFiltersRO.name, filtersDTO.name); + t.deepEqual(createTableFiltersRO.filters, filtersDTO.filters); + } catch (e) { + console.error(e); + t.fail(); + } }); currentTest = `GET /table-filters/:connectionId/all`; test.serial(`${currentTest} should return table filters`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '45'; - - const filters = { - [fieldname]: { lt: fieldvalue }, - }; - - const filtersDTO = { - name: 'Test filter', - filters: filters, - }; - - const createTableFiltersResponse = await request(app.getHttpServer()) - .post(`/table-filters/${createConnectionRO.id}/?tableName=${testTableName}`) - .send({ ...filtersDTO }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createTableFiltersRO = JSON.parse(createTableFiltersResponse.text); - t.is(createTableFiltersResponse.status, 201); - t.is(Object.hasOwn(createTableFiltersRO, 'id'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'name'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'filters'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'dynamic_column'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'createdAt'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'updatedAt'), true); - t.is(createTableFiltersRO.name, filtersDTO.name); - t.deepEqual(createTableFiltersRO.filters, filtersDTO.filters); - - const getTableFiltersResponse = await request(app.getHttpServer()) - .get(`/table-filters/${createConnectionRO.id}/all/?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableFiltersRO = JSON.parse(getTableFiltersResponse.text); - t.is(Array.isArray(getTableFiltersRO), true); - t.is(getTableFiltersRO.length, 1); - getTableFiltersRO.forEach((el) => { - t.is(Object.hasOwn(el, 'id'), true); - t.is(Object.hasOwn(el, 'name'), true); - t.is(Object.hasOwn(el, 'filters'), true); - t.is(Object.hasOwn(el, 'dynamic_column'), true); - t.is(Object.hasOwn(el, 'createdAt'), true); - t.is(Object.hasOwn(el, 'updatedAt'), true); - t.is(el.name, filtersDTO.name); - t.deepEqual(el.filters, filtersDTO.filters); - }); - } catch (e) { - console.error(e); - t.fail(); - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '45'; + + const filters = { + [fieldname]: { lt: fieldvalue }, + }; + + const filtersDTO = { + name: 'Test filter', + filters: filters, + }; + + const createTableFiltersResponse = await request(app.getHttpServer()) + .post(`/table-filters/${createConnectionRO.id}/?tableName=${testTableName}`) + .send({ ...filtersDTO }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createTableFiltersRO = JSON.parse(createTableFiltersResponse.text); + t.is(createTableFiltersResponse.status, 201); + t.is(Object.hasOwn(createTableFiltersRO, 'id'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'name'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'filters'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'dynamic_column'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'createdAt'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'updatedAt'), true); + t.is(createTableFiltersRO.name, filtersDTO.name); + t.deepEqual(createTableFiltersRO.filters, filtersDTO.filters); + + const getTableFiltersResponse = await request(app.getHttpServer()) + .get(`/table-filters/${createConnectionRO.id}/all/?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableFiltersRO = JSON.parse(getTableFiltersResponse.text); + t.is(Array.isArray(getTableFiltersRO), true); + t.is(getTableFiltersRO.length, 1); + getTableFiltersRO.forEach((el) => { + t.is(Object.hasOwn(el, 'id'), true); + t.is(Object.hasOwn(el, 'name'), true); + t.is(Object.hasOwn(el, 'filters'), true); + t.is(Object.hasOwn(el, 'dynamic_column'), true); + t.is(Object.hasOwn(el, 'createdAt'), true); + t.is(Object.hasOwn(el, 'updatedAt'), true); + t.is(el.name, filtersDTO.name); + t.deepEqual(el.filters, filtersDTO.filters); + }); + } catch (e) { + console.error(e); + t.fail(); + } }); currentTest = `PUT /table-filters/:connectionId`; test.serial(`${currentTest} should return updated table filters`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '45'; - - const filters = { - [fieldname]: { lt: fieldvalue }, - }; - - const updatedFilters = { - [fieldname]: { lt: fieldvalue }, - }; - - const filterDTOs = []; - const filtersDTO = { - name: 'Test filter', - filters: filters, - dynamic_column: { - column_name: 'id', - comparator: 'gt', - }, - }; - - const updatedFiltersDTO = { - name: 'Test filter2', - filters: updatedFilters, - }; - filterDTOs.push(filtersDTO); - filterDTOs.push(updatedFiltersDTO); - - const createTableFiltersResponse = await request(app.getHttpServer()) - .post(`/table-filters/${createConnectionRO.id}/?tableName=${testTableName}`) - .send({ ...filtersDTO }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createTableFiltersRO = JSON.parse(createTableFiltersResponse.text); - t.is(createTableFiltersResponse.status, 201); - t.is(Object.hasOwn(createTableFiltersRO, 'id'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'name'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'filters'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'dynamic_column'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'createdAt'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'updatedAt'), true); - t.is(createTableFiltersRO.name, filtersDTO.name); - t.deepEqual(createTableFiltersRO.filters, filtersDTO.filters); - - const getTableFiltersResponse = await request(app.getHttpServer()) - .get(`/table-filters/${createConnectionRO.id}/all/?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableFiltersRO = JSON.parse(getTableFiltersResponse.text); - t.is(Array.isArray(getTableFiltersRO), true); - t.is(getTableFiltersRO.length, 1); - getTableFiltersRO.forEach((el) => { - t.is(Object.hasOwn(el, 'id'), true); - t.is(Object.hasOwn(el, 'name'), true); - t.is(Object.hasOwn(el, 'filters'), true); - t.is(Object.hasOwn(el, 'dynamic_column'), true); - t.is(Object.hasOwn(el, 'createdAt'), true); - t.is(Object.hasOwn(el, 'updatedAt'), true); - t.is(el.name, filtersDTO.name); - t.deepEqual(el.filters, filtersDTO.filters); - }); - - const updateTableFiltersResponse = await request(app.getHttpServer()) - .put(`/table-filters/${createConnectionRO.id}/${createTableFiltersRO.id}`) - .send({ ...updatedFiltersDTO }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const updateTableFiltersRO = JSON.parse(updateTableFiltersResponse.text); - - t.is(updateTableFiltersResponse.status, 200); - t.is(Object.hasOwn(updateTableFiltersRO, 'id'), true); - t.is(Object.hasOwn(updateTableFiltersRO, 'name'), true); - t.is(Object.hasOwn(updateTableFiltersRO, 'filters'), true); - t.is(Object.hasOwn(updateTableFiltersRO, 'dynamic_column'), true); - t.is(Object.hasOwn(updateTableFiltersRO, 'createdAt'), true); - t.is(Object.hasOwn(updateTableFiltersRO, 'updatedAt'), true); - t.is(updateTableFiltersRO.name, updatedFiltersDTO.name); - t.is(updateTableFiltersRO.id, createTableFiltersRO.id); - t.deepEqual(updateTableFiltersRO.filters, updatedFiltersDTO.filters); - - // should return updated table filters - const getUpdatedTableFiltersResponse = await request(app.getHttpServer()) - .get(`/table-filters/${createConnectionRO.id}/all/?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const getUpdatedTableFiltersRO = JSON.parse(getUpdatedTableFiltersResponse.text); - t.is(Array.isArray(getUpdatedTableFiltersRO), true); - t.is(getUpdatedTableFiltersRO.length, 1); - getUpdatedTableFiltersRO.forEach((el) => { - t.is(Object.hasOwn(el, 'id'), true); - t.is(Object.hasOwn(el, 'name'), true); - t.is(Object.hasOwn(el, 'filters'), true); - t.is(Object.hasOwn(el, 'dynamic_column'), true); - t.is(Object.hasOwn(el, 'createdAt'), true); - t.is(Object.hasOwn(el, 'updatedAt'), true); - t.is(el.name, updatedFiltersDTO.name); - t.deepEqual(el.filters, updatedFiltersDTO.filters); - }); - } catch (e) { - console.error(e); - t.fail(); - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '45'; + + const filters = { + [fieldname]: { lt: fieldvalue }, + }; + + const updatedFilters = { + [fieldname]: { lt: fieldvalue }, + }; + + const filterDTOs = []; + const filtersDTO = { + name: 'Test filter', + filters: filters, + dynamic_column: { + column_name: 'id', + comparator: 'gt', + }, + }; + + const updatedFiltersDTO = { + name: 'Test filter2', + filters: updatedFilters, + }; + filterDTOs.push(filtersDTO); + filterDTOs.push(updatedFiltersDTO); + + const createTableFiltersResponse = await request(app.getHttpServer()) + .post(`/table-filters/${createConnectionRO.id}/?tableName=${testTableName}`) + .send({ ...filtersDTO }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createTableFiltersRO = JSON.parse(createTableFiltersResponse.text); + t.is(createTableFiltersResponse.status, 201); + t.is(Object.hasOwn(createTableFiltersRO, 'id'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'name'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'filters'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'dynamic_column'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'createdAt'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'updatedAt'), true); + t.is(createTableFiltersRO.name, filtersDTO.name); + t.deepEqual(createTableFiltersRO.filters, filtersDTO.filters); + + const getTableFiltersResponse = await request(app.getHttpServer()) + .get(`/table-filters/${createConnectionRO.id}/all/?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableFiltersRO = JSON.parse(getTableFiltersResponse.text); + t.is(Array.isArray(getTableFiltersRO), true); + t.is(getTableFiltersRO.length, 1); + getTableFiltersRO.forEach((el) => { + t.is(Object.hasOwn(el, 'id'), true); + t.is(Object.hasOwn(el, 'name'), true); + t.is(Object.hasOwn(el, 'filters'), true); + t.is(Object.hasOwn(el, 'dynamic_column'), true); + t.is(Object.hasOwn(el, 'createdAt'), true); + t.is(Object.hasOwn(el, 'updatedAt'), true); + t.is(el.name, filtersDTO.name); + t.deepEqual(el.filters, filtersDTO.filters); + }); + + const updateTableFiltersResponse = await request(app.getHttpServer()) + .put(`/table-filters/${createConnectionRO.id}/${createTableFiltersRO.id}`) + .send({ ...updatedFiltersDTO }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const updateTableFiltersRO = JSON.parse(updateTableFiltersResponse.text); + + t.is(updateTableFiltersResponse.status, 200); + t.is(Object.hasOwn(updateTableFiltersRO, 'id'), true); + t.is(Object.hasOwn(updateTableFiltersRO, 'name'), true); + t.is(Object.hasOwn(updateTableFiltersRO, 'filters'), true); + t.is(Object.hasOwn(updateTableFiltersRO, 'dynamic_column'), true); + t.is(Object.hasOwn(updateTableFiltersRO, 'createdAt'), true); + t.is(Object.hasOwn(updateTableFiltersRO, 'updatedAt'), true); + t.is(updateTableFiltersRO.name, updatedFiltersDTO.name); + t.is(updateTableFiltersRO.id, createTableFiltersRO.id); + t.deepEqual(updateTableFiltersRO.filters, updatedFiltersDTO.filters); + + // should return updated table filters + const getUpdatedTableFiltersResponse = await request(app.getHttpServer()) + .get(`/table-filters/${createConnectionRO.id}/all/?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getUpdatedTableFiltersRO = JSON.parse(getUpdatedTableFiltersResponse.text); + t.is(Array.isArray(getUpdatedTableFiltersRO), true); + t.is(getUpdatedTableFiltersRO.length, 1); + getUpdatedTableFiltersRO.forEach((el) => { + t.is(Object.hasOwn(el, 'id'), true); + t.is(Object.hasOwn(el, 'name'), true); + t.is(Object.hasOwn(el, 'filters'), true); + t.is(Object.hasOwn(el, 'dynamic_column'), true); + t.is(Object.hasOwn(el, 'createdAt'), true); + t.is(Object.hasOwn(el, 'updatedAt'), true); + t.is(el.name, updatedFiltersDTO.name); + t.deepEqual(el.filters, updatedFiltersDTO.filters); + }); + } catch (e) { + console.error(e); + t.fail(); + } }); currentTest = `GET /table-filters/:connectionId/:filterId`; test.serial(`${currentTest} should return table filters`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '45'; - - const filters = { - [fieldname]: { lt: fieldvalue }, - }; - - const filtersDTO = { - name: 'Test filter', - filters: filters, - dynamic_column: { - column_name: 'id', - comparator: 'gt', - }, - }; - - const createTableFiltersResponse = await request(app.getHttpServer()) - .post(`/table-filters/${createConnectionRO.id}/?tableName=${testTableName}`) - .send({ ...filtersDTO }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createTableFiltersRO = JSON.parse(createTableFiltersResponse.text); - t.is(createTableFiltersResponse.status, 201); - t.is(Object.hasOwn(createTableFiltersRO, 'id'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'name'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'filters'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'dynamic_column'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'createdAt'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'updatedAt'), true); - t.is(createTableFiltersRO.name, filtersDTO.name); - t.deepEqual(createTableFiltersRO.filters, filtersDTO.filters); - - const getTableFiltersResponse = await request(app.getHttpServer()) - .get(`/table-filters/${createConnectionRO.id}/${createTableFiltersRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableFiltersRO = JSON.parse(getTableFiltersResponse.text); - t.is(Object.hasOwn(getTableFiltersRO, 'id'), true); - t.is(Object.hasOwn(getTableFiltersRO, 'name'), true); - t.is(Object.hasOwn(getTableFiltersRO, 'filters'), true); - t.is(Object.hasOwn(getTableFiltersRO, 'dynamic_column'), true); - t.is(Object.hasOwn(getTableFiltersRO, 'createdAt'), true); - t.is(Object.hasOwn(getTableFiltersRO, 'updatedAt'), true); - t.is(getTableFiltersRO.name, filtersDTO.name); - t.deepEqual(getTableFiltersRO.filters, filtersDTO.filters); - t.is(getTableFiltersRO.dynamic_column.column_name, filtersDTO.dynamic_column.column_name); - t.is(getTableFiltersRO.dynamic_column.comparator, filtersDTO.dynamic_column.comparator); - } catch (e) { - console.error(e); - t.fail(); - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '45'; + + const filters = { + [fieldname]: { lt: fieldvalue }, + }; + + const filtersDTO = { + name: 'Test filter', + filters: filters, + dynamic_column: { + column_name: 'id', + comparator: 'gt', + }, + }; + + const createTableFiltersResponse = await request(app.getHttpServer()) + .post(`/table-filters/${createConnectionRO.id}/?tableName=${testTableName}`) + .send({ ...filtersDTO }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createTableFiltersRO = JSON.parse(createTableFiltersResponse.text); + t.is(createTableFiltersResponse.status, 201); + t.is(Object.hasOwn(createTableFiltersRO, 'id'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'name'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'filters'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'dynamic_column'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'createdAt'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'updatedAt'), true); + t.is(createTableFiltersRO.name, filtersDTO.name); + t.deepEqual(createTableFiltersRO.filters, filtersDTO.filters); + + const getTableFiltersResponse = await request(app.getHttpServer()) + .get(`/table-filters/${createConnectionRO.id}/${createTableFiltersRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableFiltersRO = JSON.parse(getTableFiltersResponse.text); + t.is(Object.hasOwn(getTableFiltersRO, 'id'), true); + t.is(Object.hasOwn(getTableFiltersRO, 'name'), true); + t.is(Object.hasOwn(getTableFiltersRO, 'filters'), true); + t.is(Object.hasOwn(getTableFiltersRO, 'dynamic_column'), true); + t.is(Object.hasOwn(getTableFiltersRO, 'createdAt'), true); + t.is(Object.hasOwn(getTableFiltersRO, 'updatedAt'), true); + t.is(getTableFiltersRO.name, filtersDTO.name); + t.deepEqual(getTableFiltersRO.filters, filtersDTO.filters); + t.is(getTableFiltersRO.dynamic_column.column_name, filtersDTO.dynamic_column.column_name); + t.is(getTableFiltersRO.dynamic_column.comparator, filtersDTO.dynamic_column.comparator); + } catch (e) { + console.error(e); + t.fail(); + } }); currentTest = `DELETE /table-filters/:connectionId/all`; test.serial(`${currentTest} should delete table filters`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '45'; - - const filters = { - [fieldname]: { lt: fieldvalue }, - }; - - const filtersDTO = { - name: 'Test filter', - filters: filters, - dynamic_column: { - column_name: 'id', - comparator: 'gt', - }, - }; - - const createTableFiltersResponse = await request(app.getHttpServer()) - .post(`/table-filters/${createConnectionRO.id}/?tableName=${testTableName}`) - .send({ ...filtersDTO }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createTableFiltersRO = JSON.parse(createTableFiltersResponse.text); - t.is(createTableFiltersResponse.status, 201); - t.is(Object.hasOwn(createTableFiltersRO, 'id'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'name'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'filters'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'dynamic_column'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'createdAt'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'updatedAt'), true); - t.is(createTableFiltersRO.name, filtersDTO.name); - t.deepEqual(createTableFiltersRO.filters, filtersDTO.filters); - - const deleteTableFiltersResponse = await request(app.getHttpServer()) - .delete(`/table-filters/${createConnectionRO.id}/all/?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _deleteTableFiltersRO = JSON.parse(deleteTableFiltersResponse.text); - t.is(deleteTableFiltersResponse.status, 200); - - // should return an empty array, when try to get deleted table filters - const getTableFiltersResponse = await request(app.getHttpServer()) - .get(`/table-filters/${createConnectionRO.id}/all/?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableFiltersResponse.status, 200); - t.deepEqual(getTableFiltersResponse.body, []); - } catch (e) { - console.error(e); - t.fail(); - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '45'; + + const filters = { + [fieldname]: { lt: fieldvalue }, + }; + + const filtersDTO = { + name: 'Test filter', + filters: filters, + dynamic_column: { + column_name: 'id', + comparator: 'gt', + }, + }; + + const createTableFiltersResponse = await request(app.getHttpServer()) + .post(`/table-filters/${createConnectionRO.id}/?tableName=${testTableName}`) + .send({ ...filtersDTO }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createTableFiltersRO = JSON.parse(createTableFiltersResponse.text); + t.is(createTableFiltersResponse.status, 201); + t.is(Object.hasOwn(createTableFiltersRO, 'id'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'name'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'filters'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'dynamic_column'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'createdAt'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'updatedAt'), true); + t.is(createTableFiltersRO.name, filtersDTO.name); + t.deepEqual(createTableFiltersRO.filters, filtersDTO.filters); + + const deleteTableFiltersResponse = await request(app.getHttpServer()) + .delete(`/table-filters/${createConnectionRO.id}/all/?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _deleteTableFiltersRO = JSON.parse(deleteTableFiltersResponse.text); + t.is(deleteTableFiltersResponse.status, 200); + + // should return an empty array, when try to get deleted table filters + const getTableFiltersResponse = await request(app.getHttpServer()) + .get(`/table-filters/${createConnectionRO.id}/all/?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableFiltersResponse.status, 200); + t.deepEqual(getTableFiltersResponse.body, []); + } catch (e) { + console.error(e); + t.fail(); + } }); currentTest = `DELETE /table-filters/:connectionId/:filterId`; test.serial(`${currentTest} should delete table filters`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '45'; - - const filters = { - [fieldname]: { lt: fieldvalue }, - }; - - const filtersDTO = { - name: 'Test filter', - filters: filters, - dynamic_column: { - column_name: 'id', - comparator: 'gt', - }, - }; - - const createTableFiltersResponse = await request(app.getHttpServer()) - .post(`/table-filters/${createConnectionRO.id}/?tableName=${testTableName}`) - .send({ ...filtersDTO }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createTableFiltersRO = JSON.parse(createTableFiltersResponse.text); - t.is(createTableFiltersResponse.status, 201); - t.is(Object.hasOwn(createTableFiltersRO, 'id'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'name'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'filters'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'dynamic_column'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'createdAt'), true); - t.is(Object.hasOwn(createTableFiltersRO, 'updatedAt'), true); - t.is(createTableFiltersRO.name, filtersDTO.name); - t.deepEqual(createTableFiltersRO.filters, filtersDTO.filters); - - const deleteTableFiltersResponse = await request(app.getHttpServer()) - .delete(`/table-filters/${createConnectionRO.id}/${createTableFiltersRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _deleteTableFiltersRO = JSON.parse(deleteTableFiltersResponse.text); - t.is(deleteTableFiltersResponse.status, 200); - - // should return an empty array, when try to get deleted table filters - const getTableFiltersResponse = await request(app.getHttpServer()) - .get(`/table-filters/${createConnectionRO.id}/all/?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableFiltersResponse.status, 200); - t.deepEqual(getTableFiltersResponse.body, []); - } catch (e) { - console.error(e); - t.fail(); - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '45'; + + const filters = { + [fieldname]: { lt: fieldvalue }, + }; + + const filtersDTO = { + name: 'Test filter', + filters: filters, + dynamic_column: { + column_name: 'id', + comparator: 'gt', + }, + }; + + const createTableFiltersResponse = await request(app.getHttpServer()) + .post(`/table-filters/${createConnectionRO.id}/?tableName=${testTableName}`) + .send({ ...filtersDTO }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createTableFiltersRO = JSON.parse(createTableFiltersResponse.text); + t.is(createTableFiltersResponse.status, 201); + t.is(Object.hasOwn(createTableFiltersRO, 'id'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'name'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'filters'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'dynamic_column'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'createdAt'), true); + t.is(Object.hasOwn(createTableFiltersRO, 'updatedAt'), true); + t.is(createTableFiltersRO.name, filtersDTO.name); + t.deepEqual(createTableFiltersRO.filters, filtersDTO.filters); + + const deleteTableFiltersResponse = await request(app.getHttpServer()) + .delete(`/table-filters/${createConnectionRO.id}/${createTableFiltersRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _deleteTableFiltersRO = JSON.parse(deleteTableFiltersResponse.text); + t.is(deleteTableFiltersResponse.status, 200); + + // should return an empty array, when try to get deleted table filters + const getTableFiltersResponse = await request(app.getHttpServer()) + .get(`/table-filters/${createConnectionRO.id}/all/?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableFiltersResponse.status, 200); + t.deepEqual(getTableFiltersResponse.body, []); + } catch (e) { + console.error(e); + t.fail(); + } }); currentTest = 'GET /table/rows/:slug'; test.serial( - `${currentTest} should return rows with search, with pagination, with sorting and with filters applied from created table filters + `${currentTest} should return rows with search, with pagination, with sorting and with filters applied from created table filters with search and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '45'; - - const filters = { - [fieldname]: { lt: fieldvalue }, - }; - - const filterDTOs = []; - const filtersDTO = { - name: 'Test filter', - filters: filters, - dynamic_column: { - column_name: 'id', - comparator: 'gt', - }, - }; - - const secondFiltersDTO = { - name: 'Test filter2', - filters: filters, - dynamic_column: { - column_name: 'id', - comparator: 'lt', - }, - }; - filterDTOs.push(filtersDTO); - filterDTOs.push(secondFiltersDTO); - - const createTableFiltersResponse = await request(app.getHttpServer()) - .post(`/table-filters/${createConnectionRO.id}/?tableName=${testTableName}`) - .send({ ...filtersDTO }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableFiltersResponse.status, 201); - - const createTableFiltersResponse2 = await request(app.getHttpServer()) - .post(`/table-filters/${createConnectionRO.id}/?tableName=${testTableName}`) - .send({ ...secondFiltersDTO }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableFiltersResponse2.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=200`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 200); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(Object.hasOwn(getTableRowsRO, 'saved_filters'), true); - t.is(Array.isArray(getTableRowsRO.saved_filters), true); - t.is(getTableRowsRO.saved_filters.length, 2); - getTableRowsRO.saved_filters.forEach((el) => { - t.is(Object.hasOwn(el, 'id'), true); - t.is(Object.hasOwn(el, 'name'), true); - t.is(Object.hasOwn(el, 'filters'), true); - t.is(Object.hasOwn(el, 'dynamic_column'), true); - t.is(Object.hasOwn(el, 'createdAt'), true); - t.is(Object.hasOwn(el, 'updatedAt'), true); - const foundFilterDTO = filterDTOs.find((filterDTO) => filterDTO.name === el.name); - t.is(el.name, foundFilterDTO.name); - t.deepEqual(el.filters, foundFilterDTO.filters); - }); - } catch (error) { - console.error(error); - t.fail(); - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '45'; + + const filters = { + [fieldname]: { lt: fieldvalue }, + }; + + const filterDTOs = []; + const filtersDTO = { + name: 'Test filter', + filters: filters, + dynamic_column: { + column_name: 'id', + comparator: 'gt', + }, + }; + + const secondFiltersDTO = { + name: 'Test filter2', + filters: filters, + dynamic_column: { + column_name: 'id', + comparator: 'lt', + }, + }; + filterDTOs.push(filtersDTO); + filterDTOs.push(secondFiltersDTO); + + const createTableFiltersResponse = await request(app.getHttpServer()) + .post(`/table-filters/${createConnectionRO.id}/?tableName=${testTableName}`) + .send({ ...filtersDTO }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableFiltersResponse.status, 201); + + const createTableFiltersResponse2 = await request(app.getHttpServer()) + .post(`/table-filters/${createConnectionRO.id}/?tableName=${testTableName}`) + .send({ ...secondFiltersDTO }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableFiltersResponse2.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=200`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 200); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(Object.hasOwn(getTableRowsRO, 'saved_filters'), true); + t.is(Array.isArray(getTableRowsRO.saved_filters), true); + t.is(getTableRowsRO.saved_filters.length, 2); + getTableRowsRO.saved_filters.forEach((el) => { + t.is(Object.hasOwn(el, 'id'), true); + t.is(Object.hasOwn(el, 'name'), true); + t.is(Object.hasOwn(el, 'filters'), true); + t.is(Object.hasOwn(el, 'dynamic_column'), true); + t.is(Object.hasOwn(el, 'createdAt'), true); + t.is(Object.hasOwn(el, 'updatedAt'), true); + const foundFilterDTO = filterDTOs.find((filterDTO) => filterDTO.name === el.name); + t.is(el.name, foundFilterDTO.name); + t.deepEqual(el.filters, foundFilterDTO.filters); + }); + } catch (error) { + console.error(error); + t.fail(); + } + }, ); diff --git a/backend/test/ava-tests/saas-tests/table-ibmdb2-e2e.test.ts b/backend/test/ava-tests/saas-tests/table-ibmdb2-e2e.test.ts index e3ffb0f7c..169ea3917 100644 --- a/backend/test/ava-tests/saas-tests/table-ibmdb2-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/table-ibmdb2-e2e.test.ts @@ -39,3929 +39,3929 @@ const testTables: Array = []; let currentTest; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /connection/tables/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 200); - const getTablesRO = JSON.parse(getTablesResponse.text); - - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.length > 0, true); - - const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); - - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); - t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); - t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); - t.is(getTablesRO[testTableIndex].table, testTableName); - t.is(getTablesRO[testTableIndex].permissions.visibility, true); - t.is(getTablesRO[testTableIndex].permissions.readonly, false); - t.is(getTablesRO[testTableIndex].permissions.add, true); - t.is(getTablesRO[testTableIndex].permissions.delete, true); - t.is(getTablesRO[testTableIndex].permissions.edit, true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 200); + const getTablesRO = JSON.parse(getTablesResponse.text); + + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.length > 0, true); + + const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); + + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); + t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); + t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); + t.is(getTablesRO[testTableIndex].table, testTableName); + t.is(getTablesRO[testTableIndex].permissions.visibility, true); + t.is(getTablesRO[testTableIndex].permissions.readonly, false); + t.is(getTablesRO[testTableIndex].permissions.add, true); + t.is(getTablesRO[testTableIndex].permissions.delete, true); + t.is(getTablesRO[testTableIndex].permissions.edit, true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connectionId not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = ''; - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = ''; + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connection id is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = faker.string.uuid(); - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 400); - const { message } = JSON.parse(getTablesResponse.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = faker.string.uuid(); + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 400); + const { message } = JSON.parse(getTablesResponse.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return rows of selected table without search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'ID'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[15], 'CREATED_AT'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[19], 'UPDATED_AT'), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'ID'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[15], 'CREATED_AT'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[19], 'UPDATED_AT'), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return rows of selected table with search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['ID'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createTableSettingsResponse.status, 201); - - const searchedDescription = '25'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(getTableRowsResponse.status, 200); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].ID, parseInt(searchedDescription, 10)); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'CREATED_AT'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'UPDATED_AT'), true); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['ID'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const searchedDescription = '25'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(getTableRowsResponse.status, 200); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].ID, parseInt(searchedDescription, 10)); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'CREATED_AT'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'UPDATED_AT'), true); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=1, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['ID'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Content-Type', 'application/json') - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'ID'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'ID'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'INTEGER'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['ID'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'ID'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'ID'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'INTEGER'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=3, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['ID'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'ID'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'ID'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'INTEGER'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 3); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['ID'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'ID'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'ID'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'INTEGER'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 3); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'ID'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'INTEGER'); - - //todo: rework pagination - // t.is(getTableRowsRO.pagination.total, 3); - // t.is(getTableRowsRO.pagination.lastPage, 2); - // t.is(getTableRowsRO.pagination.perPage, 2); - // t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'ID'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'INTEGER'); + + //todo: rework pagination + // t.is(getTableRowsRO.pagination.total, 3); + // t.is(getTableRowsRO.pagination.lastPage, 2); + // t.is(getTableRowsRO.pagination.perPage, 2); + // t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'ID'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'INTEGER'); - - //todo: rework pagination - // t.is(getTableRowsRO.pagination.total, 3); - // t.is(getTableRowsRO.pagination.lastPage, 2); - // t.is(getTableRowsRO.pagination.perPage, 2); - // t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'ID'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'INTEGER'); + + //todo: rework pagination + // t.is(getTableRowsRO.pagination.total, 3); + // t.is(getTableRowsRO.pagination.lastPage, 2); + // t.is(getTableRowsRO.pagination.perPage, 2); + // t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by DESC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.DESC, - 'ID', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(getTableRowsResponse.status, 200); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].ID, 42); - t.is(getTableRowsRO.rows[1].ID, 41); - t.is(getTableRowsRO.rows[41].ID, 1); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.DESC, + 'ID', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(getTableRowsResponse.status, 200); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].ID, 42); + t.is(getTableRowsRO.rows[1].ID, 41); + t.is(getTableRowsRO.rows[41].ID, 1); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by ASC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.ASC, - 'ID', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].ID, 1); - t.is(getTableRowsRO.rows[1].ID, 2); - t.is(getTableRowsRO.rows[41].ID, 42); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.ASC, + 'ID', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].ID, 1); + t.is(getTableRowsRO.rows[1].ID, 2); + t.is(getTableRowsRO.rows[41].ID, 42); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and with pagination and with sorting + `${currentTest} without search and with pagination and with sorting should return all found rows with sorting ports by DESC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'ID', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].ID, 42); - t.is(getTableRowsRO.rows[1].ID, 41); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'ID', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].ID, 42); + t.is(getTableRowsRO.rows[1].ID, 41); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'ID', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].ID, 1); - t.is(getTableRowsRO.rows[1].ID, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'ID', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].ID, 1); + t.is(getTableRowsRO.rows[1].ID, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'ID', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].ID, 39); - t.is(getTableRowsRO.rows[1].ID, 38); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'ID', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].ID, 39); + t.is(getTableRowsRO.rows[1].ID, 38); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'ID', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].ID, 38); - t.is(getTableRowsRO.rows[1].ID, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'ID', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].ID, 38); + t.is(getTableRowsRO.rows[1].ID, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'ID', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].ID, 1); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'ID', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].ID, 1); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'ID', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].ID, 1); - t.is(getTableRowsRO.rows[1].ID, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'ID', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].ID, 1); + t.is(getTableRowsRO.rows[1].ID, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'ID', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].ID, 38); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'ID', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].ID, 38); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'ID', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'ID'; - const fieldvalue = '45'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].ID, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].ID, 22); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'ID', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'ID'; + const fieldvalue = '45'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].ID, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].ID, 22); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=10 and DESC sorting and filtering'`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'ID', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'ID'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].ID, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].ID, 22); - t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[2].ID, 1); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 10); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'ID', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'ID'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].ID, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].ID, 22); + t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[2].ID, 1); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 10); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'ID', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'ID'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].ID, 1); - - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'ID', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'ID'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].ID, 1); + + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and with multi filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'ID', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'ID'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0].ID, 38); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'ID', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'ID'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0].ID, 38); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'ID', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'ID'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - createConnectionRO.id = ''; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'ID', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'ID'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + createConnectionRO.id = ''; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'ID', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'ID'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - createConnectionRO.id = faker.string.uuid(); - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 403); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'ID', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'ID'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + createConnectionRO.id = faker.string.uuid(); + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 403); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'ID', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'ID'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 400); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'ID', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'ID'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 400); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'ID', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = faker.lorem.words(1); - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTablesRO = JSON.parse(getTableRowsResponse.text); - t.is(getTablesRO.rows.length, 2); - t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTablesRO, 'pagination'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'ID', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = faker.lorem.words(1); + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTablesRO = JSON.parse(getTableRowsResponse.text); + t.is(getTablesRO.rows.length, 2); + t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTablesRO, 'pagination'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 200); - const getTableStructureRO = JSON.parse(getTableStructure.text); - - t.is(typeof getTableStructureRO, 'object'); - t.is(typeof getTableStructureRO.structure, 'object'); - t.is(getTableStructureRO.structure.length, 5); - - for (const element of getTableStructureRO.structure) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'column_default'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - t.is(Object.hasOwn(element, 'isExcluded'), true); - t.is(Object.hasOwn(element, 'isSearched'), true); - } - - t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); - - for (const element of getTableStructureRO.primaryColumns) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - } - - for (const element of getTableStructureRO.foreignKeys) { - t.is(Object.hasOwn(element, 'referenced_column_name'), true); - t.is(Object.hasOwn(element, 'referenced_table_name'), true); - t.is(Object.hasOwn(element, 'constraint_name'), true); - t.is(Object.hasOwn(element, 'column_name'), true); - } + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 200); + const getTableStructureRO = JSON.parse(getTableStructure.text); + + t.is(typeof getTableStructureRO, 'object'); + t.is(typeof getTableStructureRO.structure, 'object'); + t.is(getTableStructureRO.structure.length, 5); + + for (const element of getTableStructureRO.structure) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'column_default'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + t.is(Object.hasOwn(element, 'isExcluded'), true); + t.is(Object.hasOwn(element, 'isSearched'), true); + } + + t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); + + for (const element of getTableStructureRO.primaryColumns) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + } + + for (const element of getTableStructureRO.foreignKeys) { + t.is(Object.hasOwn(element, 'referenced_column_name'), true); + t.is(Object.hasOwn(element, 'referenced_table_name'), true); + t.is(Object.hasOwn(element, 'constraint_name'), true); + t.is(Object.hasOwn(element, 'column_name'), true); + } }); test.serial(`${currentTest} should throw an exception whe connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 404); }); test.serial(`${currentTest} should throw an exception whe connection id passed in request id incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = faker.string.uuid(); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 403); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = faker.string.uuid(); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 403); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest}should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = faker.lorem.words(1); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = faker.lorem.words(1); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should add row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addRowInTableRO = JSON.parse(addRowInTableResponse.text); - t.is(addRowInTableResponse.status, 201); - - t.is(Object.hasOwn(addRowInTableRO, 'row'), true); - t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); - t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 43); - t.is(rows[42][testTableColumnName], row[testTableColumnName]); - t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); - t.is(rows[42].ID, rows[41].ID + 1); - - // check that rows adding was logged - - const getLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getLogsResponse.status, 200); - const getLogsRO = JSON.parse(getLogsResponse.text); - t.is(Object.hasOwn(getLogsRO, 'logs'), true); - t.is(Object.hasOwn(getLogsRO, 'pagination'), true); - t.is(getLogsRO.logs.length > 0, true); - const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); - t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'ID'), true); - t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.ID, 43); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addRowInTableRO = JSON.parse(addRowInTableResponse.text); + t.is(addRowInTableResponse.status, 201); + + t.is(Object.hasOwn(addRowInTableRO, 'row'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 43); + t.is(rows[42][testTableColumnName], row[testTableColumnName]); + t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); + t.is(rows[42].ID, rows[41].ID + 1); + + // check that rows adding was logged + + const getLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getLogsResponse.status, 200); + const getLogsRO = JSON.parse(getLogsResponse.text); + t.is(Object.hasOwn(getLogsRO, 'logs'), true); + t.is(Object.hasOwn(getLogsRO, 'pagination'), true); + t.is(getLogsRO.logs.length > 0, true); + const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); + t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'ID'), true); + t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.ID, 43); }); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const fakeConnectionId = ''; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 404); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const fakeConnectionId = ''; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 404); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when row is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.PARAMETER_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.PARAMETER_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); currentTest = 'PUT /table/row/:slug'; test.serial(`${currentTest} should update row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(updateRowInTableResponse.status, 200); - t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); - t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was updated - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - const updateRowIndex = rows.map((row) => row.ID).indexOf(1); - t.is(rows.length, 42); - t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); - t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(updateRowInTableResponse.status, 200); + t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); + t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was updated + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + const updateRowIndex = rows.map((row) => row.ID).indexOf(1); + t.is(rows.length, 42); + t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); + t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = ''; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = ''; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 404); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 403); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 403); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=&ID=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=&ID=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&ID=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&ID=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=100000000`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=100000000`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/update/:connectionId'; test.serial(`${currentTest} should update multiple rows and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const requestData = { - primaryKeys: [{ ID: 1 }, { ID: 2 }], - newValues: { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(requestData)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(updateRowInTableResponse.status, 200); - t.is(updateRowInTableRO.success, true); - - // check that the rows were updated - const firstRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=1`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const firstRow = JSON.parse(firstRowResponse.text); - t.is(firstRowResponse.status, 200); - t.is(firstRow.row[testTableColumnName], fakeName); - t.is(firstRow.row[testTableSecondColumnName], fakeMail); - - const secondRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const secondRow = JSON.parse(secondRowResponse.text); - t.is(secondRowResponse.status, 200); - t.is(secondRow.row[testTableColumnName], fakeName); - t.is(secondRow.row[testTableSecondColumnName], fakeMail); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const requestData = { + primaryKeys: [{ ID: 1 }, { ID: 2 }], + newValues: { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(requestData)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(updateRowInTableResponse.status, 200); + t.is(updateRowInTableRO.success, true); + + // check that the rows were updated + const firstRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=1`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const firstRow = JSON.parse(firstRowResponse.text); + t.is(firstRowResponse.status, 200); + t.is(firstRow.row[testTableColumnName], fakeName); + t.is(firstRow.row[testTableSecondColumnName], fakeMail); + + const secondRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const secondRow = JSON.parse(secondRowResponse.text); + t.is(secondRowResponse.status, 200); + t.is(secondRow.row[testTableColumnName], fakeName); + t.is(secondRow.row[testTableSecondColumnName], fakeMail); }); currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 41); - const deletedRowIndex = rows.map((row: Record) => row.ID).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, true); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 41); + const deletedRowIndex = rows.map((row: Record) => row.ID).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, true); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&ID=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 404); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.ID).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&ID=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 404); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.ID).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = faker.string.uuid(); - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&ID=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 403); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.ID).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = faker.string.uuid(); + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&ID=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 403); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.ID).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&ID=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.ID).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&ID=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.ID).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&ID=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.ID).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&ID=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.ID).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.ID).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.ID).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.ID).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.ID).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=100000`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - t.is(deleteRowInTableResponse.status, 400); - t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=100000`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + t.is(deleteRowInTableResponse.status, 400); + t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} found row`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 200); - const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); - t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); - t.is(typeof foundRowInTableRO.row, 'object'); - t.is(typeof foundRowInTableRO.structure, 'object'); - t.is(typeof foundRowInTableRO.primaryColumns, 'object'); - t.is(typeof foundRowInTableRO.readonly_fields, 'object'); - t.is(typeof foundRowInTableRO.foreignKeys, 'object'); - t.is(foundRowInTableRO.row.ID, 1); - t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); - t.is(Object.keys(foundRowInTableRO.row).length, 5); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 200); + const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); + t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); + t.is(typeof foundRowInTableRO.row, 'object'); + t.is(typeof foundRowInTableRO.structure, 'object'); + t.is(typeof foundRowInTableRO.primaryColumns, 'object'); + t.is(typeof foundRowInTableRO.readonly_fields, 'object'); + t.is(typeof foundRowInTableRO.foreignKeys, 'object'); + t.is(foundRowInTableRO.row.ID, 1); + t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); + t.is(Object.keys(foundRowInTableRO.row).length, 5); }); test.serial(`${currentTest} should throw an exception, when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const idForSearch = 1; - createConnectionRO.id = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const idForSearch = 1; + createConnectionRO.id = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 404); }); test.serial( - `${currentTest} should throw an exception, when connection id passed in request is incorrect`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - createConnectionRO.id = faker.string.uuid(); - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 403); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - }, + `${currentTest} should throw an exception, when connection id passed in request is incorrect`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + createConnectionRO.id = faker.string.uuid(); + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 403); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + }, ); test.serial(`${currentTest} should throw an exception, when tableName in not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&ID=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&ID=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception, when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&ID=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&ID=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception, when primary key is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1000000; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1000000; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&ID=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/delete/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const primaryKeysForDeletion: Array> = [ - { - ID: 1, - }, - { - ID: 10, - }, - { - ID: 32, - }, - ]; - const deleteRowsInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) - .send(primaryKeysForDeletion) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowsInTableResponse.status, 200); - const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - // check that lines was deleted - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); - - for (const key of primaryKeysForDeletion) { - t.is( - rows.findIndex((row) => row.ID === key.id), - -1, - ); - } - - // check that table deletaion was logged - const tableLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(tableLogsResponse.status, 200); - - const tableLogsRO = JSON.parse(tableLogsResponse.text); - t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); - const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); - for (const key of primaryKeysForDeletion) { - t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); - } + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const primaryKeysForDeletion: Array> = [ + { + ID: 1, + }, + { + ID: 10, + }, + { + ID: 32, + }, + ]; + const deleteRowsInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) + .send(primaryKeysForDeletion) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowsInTableResponse.status, 200); + const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + // check that lines was deleted + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); + + for (const key of primaryKeysForDeletion) { + t.is( + rows.findIndex((row) => row.ID === key.id), + -1, + ); + } + + // check that table deletaion was logged + const tableLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(tableLogsResponse.status, 200); + + const tableLogsRO = JSON.parse(tableLogsResponse.text); + t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); + const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); + for (const key of primaryKeysForDeletion) { + t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); + } }); test.serial(`${currentTest} should test connection and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const testConnectionResponse = await request(app.getHttpServer()) - .post('/connection/test/') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse.status, 201); - const { message } = JSON.parse(testConnectionResponse.text); - t.is(message, 'Successfully connected'); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const testConnectionResponse = await request(app.getHttpServer()) + .post('/connection/test/') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse.status, 201); + const { message } = JSON.parse(testConnectionResponse.text); + t.is(message, 'Successfully connected'); }); currentTest = 'GET table/csv/:slug'; test.serial(`${currentTest} should return csv file with table data`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); }); test.serial( - `${currentTest} should return csv file with table data with search, with pagination, with sorting, + `${currentTest} should return csv file with table data with search, with pagination, with sorting, with search and pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'ID', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post( - `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - }, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'ID', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post( + `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + }, ); currentTest = 'POST /table/csv/import/:slug'; test.serial(`${currentTest} should import csv file with table data`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'ID', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post( - `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - - function deleteIdColumnsInCSVFile(filePatch: string) { - // eslint-disable-next-line security/detect-non-literal-fs-filename - const fileContent = fs.readFileSync(filePatch).toString(); - const rows = fileContent.split('\n'); - const idColumnIndex = rows[0].split(',').indexOf('ID'); - const newRows = rows.map((row) => { - const columns = row.split(','); - if (columns.length === 1) { - return row; - } - if (idColumnIndex >= 0) { - columns.splice(idColumnIndex, 1); - } - return columns.join(','); - }); - return newRows.join('\n'); - } - - const newFileContent = deleteIdColumnsInCSVFile(downloadedFilePatch); - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, newFileContent); - - const importCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) - .attach('file', downloadedFilePatch) - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - - t.is(importCsvResponse.status, 201); - //checking that the lines was added - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(getTableRowsResponse.status, 200); - const addedRows = getTableRowsRO.rows.filter((row: Record) => row.ID > testEntitiesSeedsCount); - t.is(addedRows.length, 2); + const connectionToTestDB = getTestData(mockFactory).connectionToIbmDb2; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'ID', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post( + `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + + function deleteIdColumnsInCSVFile(filePatch: string) { + // eslint-disable-next-line security/detect-non-literal-fs-filename + const fileContent = fs.readFileSync(filePatch).toString(); + const rows = fileContent.split('\n'); + const idColumnIndex = rows[0].split(',').indexOf('ID'); + const newRows = rows.map((row) => { + const columns = row.split(','); + if (columns.length === 1) { + return row; + } + if (idColumnIndex >= 0) { + columns.splice(idColumnIndex, 1); + } + return columns.join(','); + }); + return newRows.join('\n'); + } + + const newFileContent = deleteIdColumnsInCSVFile(downloadedFilePatch); + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, newFileContent); + + const importCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) + .attach('file', downloadedFilePatch) + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + + t.is(importCsvResponse.status, 201); + //checking that the lines was added + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(getTableRowsResponse.status, 200); + const addedRows = getTableRowsRO.rows.filter((row: Record) => row.ID > testEntitiesSeedsCount); + t.is(addedRows.length, 2); }); diff --git a/backend/test/ava-tests/saas-tests/table-logs-e2e.test.ts b/backend/test/ava-tests/saas-tests/table-logs-e2e.test.ts index 57e9d9c37..f484d5dbd 100644 --- a/backend/test/ava-tests/saas-tests/table-logs-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/table-logs-e2e.test.ts @@ -32,309 +32,309 @@ let _testUtils: TestUtils; const mockFactory = new MockFactory(); test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /logs/:slug'; test.serial(`${currentTest} should return all found logs in connection`, async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - /* eslint-disable */ - const created_at = new Date(); - const updated_at = new Date(); - const addRowInTable = await request(app.getHttpServer()) - .post(`/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) - .send({ - [testData.firstTableInfo.testTableColumnName]: randomName, - [testData.firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set('Cookie', testData.users.simpleUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTable.status, 201); - - const getTableLogs = await request(app.getHttpServer()) - .get(`/logs/${testData.connections.firstId}`) - .set('Cookie', testData.users.adminUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const getRowInTableRO = JSON.parse(getTableLogs.text); - - t.is(getRowInTableRO.logs.length, 1); - t.is(Object.hasOwn(getRowInTableRO.logs[0], 'table_name'), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], 'received_data'), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], 'old_data'), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], 'cognitoUserName'), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], 'email'), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], 'operationType'), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], 'operationStatusResult'), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], 'createdAt'), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], 'connection_id'), true); - } catch (error) { - console.error(error); - throw error; - } + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + /* eslint-disable */ + const created_at = new Date(); + const updated_at = new Date(); + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) + .send({ + [testData.firstTableInfo.testTableColumnName]: randomName, + [testData.firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTable.status, 201); + + const getTableLogs = await request(app.getHttpServer()) + .get(`/logs/${testData.connections.firstId}`) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getRowInTableRO = JSON.parse(getTableLogs.text); + + t.is(getRowInTableRO.logs.length, 1); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'table_name'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'received_data'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'old_data'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'cognitoUserName'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'email'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'operationType'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'operationStatusResult'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'createdAt'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'connection_id'), true); + } catch (error) { + console.error(error); + throw error; + } }); test.serial( - `${currentTest} should return all found logs in connection with included searched primary keys`, - async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - /* eslint-disable */ - const created_at = new Date(); - const updated_at = new Date(); - const addRowInTable = await request(app.getHttpServer()) - .post(`/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) - .send({ - [testData.firstTableInfo.testTableColumnName]: randomName, - [testData.firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set('Cookie', testData.users.simpleUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTable.status, 201); - - const getTableLogs = await request(app.getHttpServer()) - .get(`/logs/${testData.connections.firstId}`) - .set('Cookie', testData.users.adminUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const getLogsInTableRO = JSON.parse(getTableLogs.text); - - t.is(getLogsInTableRO.logs.length, 1); - t.is(Object.hasOwn(getLogsInTableRO.logs[0], 'affected_primary_key'), true); - const searchedAffectedPrimaryKey = JSON.stringify(getLogsInTableRO.logs[0].affected_primary_key); - - let additionalRowAddResponse = await request(app.getHttpServer()) - .post(`/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) - .send({ - [testData.firstTableInfo.testTableColumnName]: faker.person.firstName(), - [testData.firstTableInfo.testTableSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - }) - .set('Cookie', testData.users.simpleUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(additionalRowAddResponse.status, 201); - - additionalRowAddResponse = await request(app.getHttpServer()) - .post(`/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) - .send({ - [testData.firstTableInfo.testTableColumnName]: faker.person.firstName(), - [testData.firstTableInfo.testTableSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - }) - .set('Cookie', testData.users.simpleUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(additionalRowAddResponse.status, 201); - - additionalRowAddResponse = await request(app.getHttpServer()) - .post(`/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) - .send({ - [testData.firstTableInfo.testTableColumnName]: faker.person.firstName(), - [testData.firstTableInfo.testTableSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - }) - .set('Cookie', testData.users.simpleUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(additionalRowAddResponse.status, 201); - - additionalRowAddResponse = await request(app.getHttpServer()) - .post(`/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) - .send({ - [testData.firstTableInfo.testTableColumnName]: faker.person.firstName(), - [testData.firstTableInfo.testTableSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - }) - .set('Cookie', testData.users.simpleUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(additionalRowAddResponse.status, 201); - - //check that logs was created - - const getTableLogsAfterAddingExtraRows = await request(app.getHttpServer()) - .get(`/logs/${testData.connections.firstId}`) - .set('Cookie', testData.users.adminUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const getRowAfterAddingExtraRowsRO = JSON.parse(getTableLogsAfterAddingExtraRows.text); - - t.is(getRowAfterAddingExtraRowsRO.logs.length, 5); - - const getTableLogsSearched = await request(app.getHttpServer()) - .get(`/logs/${testData.connections.firstId}?affected_primary_key=${searchedAffectedPrimaryKey}`) - .set('Cookie', testData.users.adminUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getRowInTableSearchedRO = JSON.parse(getTableLogsSearched.text); - t.is(getTableLogsSearched.status, 200); - t.is(getRowInTableSearchedRO.logs.length, 1); - t.is(JSON.stringify(getRowInTableSearchedRO.logs[0].affected_primary_key), searchedAffectedPrimaryKey); - } catch (error) { - console.error(error); - throw error; - } - }, + `${currentTest} should return all found logs in connection with included searched primary keys`, + async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + /* eslint-disable */ + const created_at = new Date(); + const updated_at = new Date(); + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) + .send({ + [testData.firstTableInfo.testTableColumnName]: randomName, + [testData.firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTable.status, 201); + + const getTableLogs = await request(app.getHttpServer()) + .get(`/logs/${testData.connections.firstId}`) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getLogsInTableRO = JSON.parse(getTableLogs.text); + + t.is(getLogsInTableRO.logs.length, 1); + t.is(Object.hasOwn(getLogsInTableRO.logs[0], 'affected_primary_key'), true); + const searchedAffectedPrimaryKey = JSON.stringify(getLogsInTableRO.logs[0].affected_primary_key); + + let additionalRowAddResponse = await request(app.getHttpServer()) + .post(`/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) + .send({ + [testData.firstTableInfo.testTableColumnName]: faker.person.firstName(), + [testData.firstTableInfo.testTableSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + }) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(additionalRowAddResponse.status, 201); + + additionalRowAddResponse = await request(app.getHttpServer()) + .post(`/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) + .send({ + [testData.firstTableInfo.testTableColumnName]: faker.person.firstName(), + [testData.firstTableInfo.testTableSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + }) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(additionalRowAddResponse.status, 201); + + additionalRowAddResponse = await request(app.getHttpServer()) + .post(`/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) + .send({ + [testData.firstTableInfo.testTableColumnName]: faker.person.firstName(), + [testData.firstTableInfo.testTableSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + }) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(additionalRowAddResponse.status, 201); + + additionalRowAddResponse = await request(app.getHttpServer()) + .post(`/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) + .send({ + [testData.firstTableInfo.testTableColumnName]: faker.person.firstName(), + [testData.firstTableInfo.testTableSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + }) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(additionalRowAddResponse.status, 201); + + //check that logs was created + + const getTableLogsAfterAddingExtraRows = await request(app.getHttpServer()) + .get(`/logs/${testData.connections.firstId}`) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getRowAfterAddingExtraRowsRO = JSON.parse(getTableLogsAfterAddingExtraRows.text); + + t.is(getRowAfterAddingExtraRowsRO.logs.length, 5); + + const getTableLogsSearched = await request(app.getHttpServer()) + .get(`/logs/${testData.connections.firstId}?affected_primary_key=${searchedAffectedPrimaryKey}`) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getRowInTableSearchedRO = JSON.parse(getTableLogsSearched.text); + t.is(getTableLogsSearched.status, 200); + t.is(getRowInTableSearchedRO.logs.length, 1); + t.is(JSON.stringify(getRowInTableSearchedRO.logs[0].affected_primary_key), searchedAffectedPrimaryKey); + } catch (error) { + console.error(error); + throw error; + } + }, ); test.serial( - `${currentTest} should not return all found logs in connection, when table audit is disabled in connection'`, - async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - - const updateConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); - - const updateConnectionResponse = await request(app.getHttpServer()) - .put(`/connection/${connections.firstId}`) - .send(updateConnection) - .set('Cookie', adminUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateConnectionResponse.status, 200); - - const newConnectionProperties = mockFactory.generateConnectionPropertiesUserExcluded(null, false); - - const createConnectionPropertiesResponse = await request(app.getHttpServer()) - .post(`/connection/properties/${connections.firstId}`) - .send(newConnectionProperties) - .set('Cookie', adminUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createConnectionPropertiesResponse.status, 201); - - const addRowInTable = await request(app.getHttpServer()) - .post(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) - .send({ - [firstTableInfo.testTableColumnName]: randomName, - [firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set('Cookie', simpleUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTable.status, 201); - - const getTableLogs = await request(app.getHttpServer()) - .get(`/logs/${connections.firstId}`) - .set('Cookie', simpleUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const getRowInTableRO = JSON.parse(getTableLogs.text); - - t.is(getRowInTableRO.logs.length, 0); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should not return all found logs in connection, when table audit is disabled in connection'`, + async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + + const updateConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); + + const updateConnectionResponse = await request(app.getHttpServer()) + .put(`/connection/${connections.firstId}`) + .send(updateConnection) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateConnectionResponse.status, 200); + + const newConnectionProperties = mockFactory.generateConnectionPropertiesUserExcluded(null, false); + + const createConnectionPropertiesResponse = await request(app.getHttpServer()) + .post(`/connection/properties/${connections.firstId}`) + .send(newConnectionProperties) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createConnectionPropertiesResponse.status, 201); + + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .send({ + [firstTableInfo.testTableColumnName]: randomName, + [firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTable.status, 201); + + const getTableLogs = await request(app.getHttpServer()) + .get(`/logs/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getRowInTableRO = JSON.parse(getTableLogs.text); + + t.is(getRowInTableRO.logs.length, 0); + } catch (e) { + console.error(e); + throw e; + } + }, ); currentTest = 'GET /logs/export/:connectionId'; test.serial(`${currentTest} should return all found logs in connection as csv`, async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - - const testTableName = testData.firstTableInfo.testTableName; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - /* eslint-disable */ - const created_at = new Date(); - const updated_at = new Date(); - const addRowInTable = await request(app.getHttpServer()) - .post(`/table/row/${testData.connections.firstId}?tableName=${testTableName}`) - .send({ - [testData.firstTableInfo.testTableColumnName]: randomName, - [testData.firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set('Cookie', testData.users.simpleUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTable.status, 201); - - const getTableLogsCSV = await request(app.getHttpServer()) - .get(`/logs/export/${testData.connections.firstId}`) - .set('Cookie', testData.users.adminUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - if (getTableLogsCSV.status !== 201) { - console.log(getTableLogsCSV.text); - } - t.is(getTableLogsCSV.status, 200); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableLogsCSV.body); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - } catch (error) { - console.error(error); - throw error; - } + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + + const testTableName = testData.firstTableInfo.testTableName; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + /* eslint-disable */ + const created_at = new Date(); + const updated_at = new Date(); + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${testData.connections.firstId}?tableName=${testTableName}`) + .send({ + [testData.firstTableInfo.testTableColumnName]: randomName, + [testData.firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTable.status, 201); + + const getTableLogsCSV = await request(app.getHttpServer()) + .get(`/logs/export/${testData.connections.firstId}`) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + if (getTableLogsCSV.status !== 201) { + console.log(getTableLogsCSV.text); + } + t.is(getTableLogsCSV.status, 200); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableLogsCSV.body); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + } catch (error) { + console.error(error); + throw error; + } }); diff --git a/backend/test/ava-tests/saas-tests/table-mongodb-e2e.test.ts b/backend/test/ava-tests/saas-tests/table-mongodb-e2e.test.ts index 966ca115d..0032ff081 100644 --- a/backend/test/ava-tests/saas-tests/table-mongodb-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/table-mongodb-e2e.test.ts @@ -39,3964 +39,3964 @@ const testTables: Array = []; let currentTest; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication() as any; - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication() as any; + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /connection/tables/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTablesRO = JSON.parse(getTablesResponse.text); - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.length > 0, true); - - const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); - - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); - t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); - t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); - t.is(getTablesRO[testTableIndex].table, testTableName); - t.is(getTablesRO[testTableIndex].permissions.visibility, true); - t.is(getTablesRO[testTableIndex].permissions.readonly, false); - t.is(getTablesRO[testTableIndex].permissions.add, true); - t.is(getTablesRO[testTableIndex].permissions.delete, true); - t.is(getTablesRO[testTableIndex].permissions.edit, true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTablesRO = JSON.parse(getTablesResponse.text); + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.length > 0, true); + + const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); + + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); + t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); + t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); + t.is(getTablesRO[testTableIndex].table, testTableName); + t.is(getTablesRO[testTableIndex].permissions.visibility, true); + t.is(getTablesRO[testTableIndex].permissions.readonly, false); + t.is(getTablesRO[testTableIndex].permissions.add, true); + t.is(getTablesRO[testTableIndex].permissions.delete, true); + t.is(getTablesRO[testTableIndex].permissions.edit, true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connectionId not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = ''; - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = ''; + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connection id is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = faker.string.uuid(); - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 400); - const { message } = JSON.parse(getTablesResponse.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = faker.string.uuid(); + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 400); + const { message } = JSON.parse(getTablesResponse.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return rows of selected table without search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(Object.hasOwn(getTableRowsRO, 'large_dataset'), true); - t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(Object.hasOwn(getTableRowsRO.rows[0], '_id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(Object.hasOwn(getTableRowsRO, 'large_dataset'), true); + t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(Object.hasOwn(getTableRowsRO.rows[0], '_id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return rows of selected table with search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['_id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createTableSettingsResponse.status, 201); - - const searchedDescription = insertedSearchedIds.find((id) => id.number === 5)._id; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0]._id, searchedDescription); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['_id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const searchedDescription = insertedSearchedIds.find((id) => id.number === 5)._id; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0]._id, searchedDescription); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=1, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['_id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Content-Type', 'application/json') - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(Object.hasOwn(getTableRowsRO.rows[0], '_id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, '_id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['_id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(Object.hasOwn(getTableRowsRO.rows[0], '_id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, '_id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=3, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['_id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(Object.hasOwn(getTableRowsRO.rows[0], '_id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, '_id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 3); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['_id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(Object.hasOwn(getTableRowsRO.rows[0], '_id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, '_id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 3); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, '_id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, '_id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, '_id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, '_id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'string'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by DESC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.DESC, - '_id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - // t.is(getTableRowsRO.rows[0]._id, 42); - // t.is(getTableRowsRO.rows[1]._id, 41); - // t.is(getTableRowsRO.rows[41]._id, 1); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.DESC, + '_id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + // t.is(getTableRowsRO.rows[0]._id, 42); + // t.is(getTableRowsRO.rows[1]._id, 41); + // t.is(getTableRowsRO.rows[41]._id, 1); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by ASC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.ASC, - '_id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - const searchedLastId = insertedSearchedIds.find((id) => id.number === 41)._id; - const searchedFirstId = insertedSearchedIds.find((id) => id.number === 0)._id; - const searchedSecondId = insertedSearchedIds.find((id) => id.number === 1)._id; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(getTableRowsRO.rows[0]._id, searchedFirstId); - t.is(getTableRowsRO.rows[1]._id, searchedSecondId); - t.is(getTableRowsRO.rows[41]._id, searchedLastId); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.ASC, + '_id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + const searchedLastId = insertedSearchedIds.find((id) => id.number === 41)._id; + const searchedFirstId = insertedSearchedIds.find((id) => id.number === 0)._id; + const searchedSecondId = insertedSearchedIds.find((id) => id.number === 1)._id; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(getTableRowsRO.rows[0]._id, searchedFirstId); + t.is(getTableRowsRO.rows[1]._id, searchedSecondId); + t.is(getTableRowsRO.rows[41]._id, searchedLastId); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and with pagination and with sorting + `${currentTest} without search and with pagination and with sorting should return all found rows with sorting ports by DESC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - '_id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - const searchedLastId = insertedSearchedIds.find((id) => id.number === 1)._id; - - const preSearchedLastId = insertedSearchedIds.find((id) => id.number === 0)._id; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(getTableRowsRO.rows[0]._id, preSearchedLastId); - t.is(getTableRowsRO.rows[1]._id, searchedLastId); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + '_id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + const searchedLastId = insertedSearchedIds.find((id) => id.number === 1)._id; + + const preSearchedLastId = insertedSearchedIds.find((id) => id.number === 0)._id; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(getTableRowsRO.rows[0]._id, preSearchedLastId); + t.is(getTableRowsRO.rows[1]._id, searchedLastId); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - '_id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - const searchedFirstId = insertedSearchedIds.find((id) => id.number === 0)._id; - - const preSearchedSecondId = insertedSearchedIds.find((id) => id.number === 1)._id; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(getTableRowsRO.rows[0]._id, searchedFirstId); - t.is(getTableRowsRO.rows[1]._id, preSearchedSecondId); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + '_id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + const searchedFirstId = insertedSearchedIds.find((id) => id.number === 0)._id; + + const preSearchedSecondId = insertedSearchedIds.find((id) => id.number === 1)._id; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(getTableRowsRO.rows[0]._id, searchedFirstId); + t.is(getTableRowsRO.rows[1]._id, preSearchedSecondId); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - '_id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - const searchedFirstId = insertedSearchedIds.find((id) => id.number === 3)._id; - - const searchedSecondId = insertedSearchedIds.find((id) => id.number === 4)._id; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(getTableRowsRO.rows[0]._id, searchedFirstId); - t.is(getTableRowsRO.rows[1]._id, searchedSecondId); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + '_id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + const searchedFirstId = insertedSearchedIds.find((id) => id.number === 3)._id; + + const searchedSecondId = insertedSearchedIds.find((id) => id.number === 4)._id; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(getTableRowsRO.rows[0]._id, searchedFirstId); + t.is(getTableRowsRO.rows[1]._id, searchedSecondId); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - '_id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - const searchedFirstId = insertedSearchedIds.find((id) => id.number === 0)._id; - - const searchedSecondId = insertedSearchedIds.find((id) => id.number === 21)._id; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); - t.is(getTableRowsRO.rows[0]._id, searchedFirstId); - t.is(getTableRowsRO.rows[1]._id, searchedSecondId); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + '_id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + const searchedFirstId = insertedSearchedIds.find((id) => id.number === 0)._id; + + const searchedSecondId = insertedSearchedIds.find((id) => id.number === 21)._id; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 6); + t.is(getTableRowsRO.rows[0]._id, searchedFirstId); + t.is(getTableRowsRO.rows[1]._id, searchedSecondId); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - '_id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - const searchedFirstId = insertedSearchedIds.find((id) => id.number === 37)._id; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0]._id, searchedFirstId); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + '_id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + const searchedFirstId = insertedSearchedIds.find((id) => id.number === 37)._id; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0]._id, searchedFirstId); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - '_id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const searchedFirstId = insertedSearchedIds.find((id) => id.number === 0)._id; - const searchedSecondId = insertedSearchedIds.find((id) => id.number === 21)._id; - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0]._id, searchedFirstId); - t.is(getTableRowsRO.rows[1]._id, searchedSecondId); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + '_id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const searchedFirstId = insertedSearchedIds.find((id) => id.number === 0)._id; + const searchedSecondId = insertedSearchedIds.find((id) => id.number === 21)._id; + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0]._id, searchedFirstId); + t.is(getTableRowsRO.rows[1]._id, searchedSecondId); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - '_id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - const searchedFirstId = insertedSearchedIds.find((id) => id.number === 37)._id; - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - t.is(getTableRowsRO.rows[0]._id, searchedFirstId); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + '_id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + const searchedFirstId = insertedSearchedIds.find((id) => id.number === 37)._id; + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + t.is(getTableRowsRO.rows[0]._id, searchedFirstId); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); // todo: rework for other tables after removing old endpoint test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and filtering in body`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - '_id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'age'; - const fieldvalue = 18; - - const filters = { - [fieldname]: { lt: fieldvalue }, - }; - - const getTableRowsResponse = await request(app.getHttpServer()) - .post( - `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .send({ filters }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - - const foundId = insertedSearchedIds.find((id) => id.number === 0)._id; - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0]._id, foundId); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + '_id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'age'; + const fieldvalue = 18; + + const filters = { + [fieldname]: { lt: fieldvalue }, + }; + + const getTableRowsResponse = await request(app.getHttpServer()) + .post( + `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .send({ filters }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + + const foundId = insertedSearchedIds.find((id) => id.number === 0)._id; + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0]._id, foundId); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=10 and DESC sorting and filtering'`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - '_id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'age'; - const fieldvalue = 18; - - const filters = { - [fieldname]: { lt: fieldvalue }, - }; - - const getTableRowsResponse = await request(app.getHttpServer()) - .post( - `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10`, - ) - .send({ filters }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 201); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - - const foundId = insertedSearchedIds.find((id) => id.number === 0)._id; - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0]._id, foundId); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 10); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + '_id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'age'; + const fieldvalue = 18; + + const filters = { + [fieldname]: { lt: fieldvalue }, + }; + + const getTableRowsResponse = await request(app.getHttpServer()) + .post( + `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10`, + ) + .send({ filters }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 201); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + + const foundId = insertedSearchedIds.find((id) => id.number === 0)._id; + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0]._id, foundId); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 10); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and with multi filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - '_id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'age'; - const fieldGtvalue = 14; - const fieldLtvalue = 95; - - const filters = { - [fieldname]: { lt: fieldLtvalue, gt: fieldGtvalue }, - }; - - const getTableRowsResponse = await request(app.getHttpServer()) - .post( - `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=3`, - ) - .send({ filters }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 201); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); - - const findRowId = insertedSearchedIds.find((id) => id.number === 21)._id; - - t.is(getTableRowsRO.rows[0]._id, findRowId); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 3); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, insertedSearchedIds } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + '_id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'age'; + const fieldGtvalue = 14; + const fieldLtvalue = 95; + + const filters = { + [fieldname]: { lt: fieldLtvalue, gt: fieldGtvalue }, + }; + + const getTableRowsResponse = await request(app.getHttpServer()) + .post( + `/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=3`, + ) + .send({ filters }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 201); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 6); + + const findRowId = insertedSearchedIds.find((id) => id.number === 21)._id; + + t.is(getTableRowsRO.rows[0]._id, findRowId); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 3); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - '_id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = '_id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - createConnectionRO.id = ''; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + '_id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = '_id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + createConnectionRO.id = ''; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - '_id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = '_id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - createConnectionRO.id = faker.string.uuid(); - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 403); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + '_id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = '_id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + createConnectionRO.id = faker.string.uuid(); + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 403); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - '_id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = '_id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 400); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + '_id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = '_id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 400); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - '_id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = faker.lorem.words(1); - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTablesRO = JSON.parse(getTableRowsResponse.text); - t.is(getTablesRO.rows.length, 2); - t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTablesRO, 'pagination'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + '_id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = faker.lorem.words(1); + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTablesRO = JSON.parse(getTableRowsResponse.text); + t.is(getTablesRO.rows.length, 2); + t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTablesRO, 'pagination'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 200); - const getTableStructureRO = JSON.parse(getTableStructure.text); - - t.is(typeof getTableStructureRO, 'object'); - t.is(typeof getTableStructureRO.structure, 'object'); - t.is(getTableStructureRO.structure.length, 6); - - for (const element of getTableStructureRO.structure) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'column_default'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - t.is(Object.hasOwn(element, 'isExcluded'), true); - t.is(Object.hasOwn(element, 'isSearched'), true); - } - - t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); - - for (const element of getTableStructureRO.primaryColumns) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - } - - for (const element of getTableStructureRO.foreignKeys) { - t.is(Object.hasOwn(element, 'referenced_column_name'), true); - t.is(Object.hasOwn(element, 'referenced_table_name'), true); - t.is(Object.hasOwn(element, 'constraint_name'), true); - t.is(Object.hasOwn(element, 'column_name'), true); - } + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 200); + const getTableStructureRO = JSON.parse(getTableStructure.text); + + t.is(typeof getTableStructureRO, 'object'); + t.is(typeof getTableStructureRO.structure, 'object'); + t.is(getTableStructureRO.structure.length, 6); + + for (const element of getTableStructureRO.structure) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'column_default'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + t.is(Object.hasOwn(element, 'isExcluded'), true); + t.is(Object.hasOwn(element, 'isSearched'), true); + } + + t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); + + for (const element of getTableStructureRO.primaryColumns) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + } + + for (const element of getTableStructureRO.foreignKeys) { + t.is(Object.hasOwn(element, 'referenced_column_name'), true); + t.is(Object.hasOwn(element, 'referenced_table_name'), true); + t.is(Object.hasOwn(element, 'constraint_name'), true); + t.is(Object.hasOwn(element, 'column_name'), true); + } }); test.serial(`${currentTest} should throw an exception whe connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 404); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 404); }); test.serial(`${currentTest} should throw an exception whe connection id passed in request id incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = faker.string.uuid(); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 403); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = faker.string.uuid(); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 403); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest}should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = faker.lorem.words(1); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = faker.lorem.words(1); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should add row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addRowInTableRO = JSON.parse(addRowInTableResponse.text); - t.is(addRowInTableResponse.status, 201); - - t.is(Object.hasOwn(addRowInTableRO, 'row'), true); - t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); - t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 43); - t.is(rows[42][testTableColumnName], row[testTableColumnName]); - t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); - - // check that rows adding was logged - - const getLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getLogsResponse.status, 200); - const getLogsRO = JSON.parse(getLogsResponse.text); - t.is(Object.hasOwn(getLogsRO, 'logs'), true); - t.is(Object.hasOwn(getLogsRO, 'pagination'), true); - t.is(getLogsRO.logs.length > 0, true); - const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); - t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, '_id'), true); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addRowInTableRO = JSON.parse(addRowInTableResponse.text); + t.is(addRowInTableResponse.status, 201); + + t.is(Object.hasOwn(addRowInTableRO, 'row'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 43); + t.is(rows[42][testTableColumnName], row[testTableColumnName]); + t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); + + // check that rows adding was logged + + const getLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getLogsResponse.status, 200); + const getLogsRO = JSON.parse(getLogsResponse.text); + t.is(Object.hasOwn(getLogsRO, 'logs'), true); + t.is(Object.hasOwn(getLogsRO, 'pagination'), true); + t.is(getLogsRO.logs.length > 0, true); + const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); + t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, '_id'), true); }); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - _id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const fakeConnectionId = ''; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 404); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + _id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const fakeConnectionId = ''; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 404); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - _id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + _id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when row is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.PARAMETER_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.PARAMETER_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - _id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.number.int({ min: 1, max: 10000 })}`; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + _id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.number.int({ min: 1, max: 10000 })}`; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); currentTest = 'PUT /table/row/:slug'; test.serial(`${currentTest} should update row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const foundIdForUpdate = insertedSearchedIds[0]._id; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${foundIdForUpdate}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 200); - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); - t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was updated - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - const updateRowIndex = rows.map((row) => row._id).indexOf(foundIdForUpdate); - t.is(rows.length, 42); - t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); - t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const foundIdForUpdate = insertedSearchedIds[0]._id; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${foundIdForUpdate}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 200); + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); + t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was updated + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + const updateRowIndex = rows.map((row) => row._id).indexOf(foundIdForUpdate); + t.is(rows.length, 42); + t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); + t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = ''; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = ''; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 404); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 403); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 403); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=&_id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=&_id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=100000000`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 500); - const responseObject = JSON.parse(updateRowInTableResponse.text); - t.is(responseObject.originalMessage, `Invalid object id format`); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=100000000`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 500); + const responseObject = JSON.parse(updateRowInTableResponse.text); + t.is(responseObject.originalMessage, `Invalid object id format`); + }, ); currentTest = 'PUT /table/rows/update/:connectionId'; test.serial(`${currentTest} should update multiple rows and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const foundFirstIdForUpdate = insertedSearchedIds[0]._id; - const foundSecondIdForUpdate = insertedSearchedIds[1]._id; - const requestData = { - primaryKeys: [{ _id: foundFirstIdForUpdate }, { _id: foundSecondIdForUpdate }], - newValues: { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(requestData)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(updateRowInTableResponse.status, 200); - t.is(updateRowInTableRO.success, true); - - // check that the rows were updated - const firstRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${foundFirstIdForUpdate}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const firstRow = JSON.parse(firstRowResponse.text); - t.is(firstRowResponse.status, 200); - t.is(firstRow.row[testTableColumnName], fakeName); - t.is(firstRow.row[testTableSecondColumnName], fakeMail); - - const secondRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${foundSecondIdForUpdate}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const secondRow = JSON.parse(secondRowResponse.text); - t.is(secondRowResponse.status, 200); - t.is(secondRow.row[testTableColumnName], fakeName); - t.is(secondRow.row[testTableSecondColumnName], fakeMail); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const foundFirstIdForUpdate = insertedSearchedIds[0]._id; + const foundSecondIdForUpdate = insertedSearchedIds[1]._id; + const requestData = { + primaryKeys: [{ _id: foundFirstIdForUpdate }, { _id: foundSecondIdForUpdate }], + newValues: { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(requestData)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(updateRowInTableResponse.status, 200); + t.is(updateRowInTableRO.success, true); + + // check that the rows were updated + const firstRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${foundFirstIdForUpdate}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const firstRow = JSON.parse(firstRowResponse.text); + t.is(firstRowResponse.status, 200); + t.is(firstRow.row[testTableColumnName], fakeName); + t.is(firstRow.row[testTableSecondColumnName], fakeMail); + + const secondRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${foundSecondIdForUpdate}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const secondRow = JSON.parse(secondRowResponse.text); + t.is(secondRowResponse.status, 200); + t.is(secondRow.row[testTableColumnName], fakeName); + t.is(secondRow.row[testTableSecondColumnName], fakeMail); }); currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0]._id; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 41); - const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, true); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0]._id; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 41); + const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, true); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0]._id; - const connectionId = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&_id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 404); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0]._id; + const connectionId = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&_id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 404); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0]._id; - const connectionId = faker.string.uuid(); - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&_id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 403); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0]._id; + const connectionId = faker.string.uuid(); + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&_id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 403); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0]._id; - const fakeTableName = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0]._id; + const fakeTableName = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0]._id; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0]._id; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0]._id; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0]._id; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = insertedSearchedIds[0]._id; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = insertedSearchedIds[0]._id; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row._id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=100000`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - t.is(deleteRowInTableResponse.status, 500); - t.is(deleteRowInTableRO.originalMessage, `Invalid object id format`); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=100000`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + t.is(deleteRowInTableResponse.status, 500); + t.is(deleteRowInTableRO.originalMessage, `Invalid object id format`); + }, ); currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} found row`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = insertedSearchedIds[0]._id; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 200); - const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); - t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); - t.is(typeof foundRowInTableRO.row, 'object'); - t.is(typeof foundRowInTableRO.structure, 'object'); - t.is(typeof foundRowInTableRO.primaryColumns, 'object'); - t.is(typeof foundRowInTableRO.readonly_fields, 'object'); - t.is(typeof foundRowInTableRO.foreignKeys, 'object'); - t.is(foundRowInTableRO.row._id, idForSearch); - t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); - t.is(Object.keys(foundRowInTableRO.row).length, 6); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = insertedSearchedIds[0]._id; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 200); + const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); + t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); + t.is(typeof foundRowInTableRO.row, 'object'); + t.is(typeof foundRowInTableRO.structure, 'object'); + t.is(typeof foundRowInTableRO.primaryColumns, 'object'); + t.is(typeof foundRowInTableRO.readonly_fields, 'object'); + t.is(typeof foundRowInTableRO.foreignKeys, 'object'); + t.is(foundRowInTableRO.row._id, idForSearch); + t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); + t.is(Object.keys(foundRowInTableRO.row).length, 6); }); test.serial(`${currentTest} should throw an exception, when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const idForSearch = 1; - createConnectionRO.id = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const idForSearch = 1; + createConnectionRO.id = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 404); }); test.serial( - `${currentTest} should throw an exception, when connection id passed in request is incorrect`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - createConnectionRO.id = faker.string.uuid(); - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 403); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - }, + `${currentTest} should throw an exception, when connection id passed in request is incorrect`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + createConnectionRO.id = faker.string.uuid(); + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 403); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + }, ); test.serial(`${currentTest} should throw an exception, when tableName in not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception, when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&_id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception, when primary key is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = insertedSearchedIds[0]._id; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = insertedSearchedIds[0]._id; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = '6604197dab8d910eb77783f9'; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const findRowResponse = JSON.parse(foundRowInTableResponse.text); - t.is(findRowResponse.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = '6604197dab8d910eb77783f9'; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&_id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const findRowResponse = JSON.parse(foundRowInTableResponse.text); + t.is(findRowResponse.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/delete/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const primaryKeysForDeletion: Array> = [ - { - _id: insertedSearchedIds[0]._id, - }, - { - _id: insertedSearchedIds[9]._id, - }, - { - _id: insertedSearchedIds[31]._id, - }, - ]; - const deleteRowsInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) - .send(primaryKeysForDeletion) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowsInTableResponse.status, 200); - const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - // check that lines was deleted - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); - - for (const key of primaryKeysForDeletion) { - t.is( - rows.findIndex((row) => row._id === key._id), - -1, - ); - } - - // check that table deletaion was logged - const tableLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(tableLogsResponse.status, 200); - - const tableLogsRO = JSON.parse(tableLogsResponse.text); - t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); - const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); - for (const key of primaryKeysForDeletion) { - t.is(onlyDeleteLogs.findIndex((log) => log.received_data._id === key._id) >= 0, true); - } + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const primaryKeysForDeletion: Array> = [ + { + _id: insertedSearchedIds[0]._id, + }, + { + _id: insertedSearchedIds[9]._id, + }, + { + _id: insertedSearchedIds[31]._id, + }, + ]; + const deleteRowsInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) + .send(primaryKeysForDeletion) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowsInTableResponse.status, 200); + const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + // check that lines was deleted + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); + + for (const key of primaryKeysForDeletion) { + t.is( + rows.findIndex((row) => row._id === key._id), + -1, + ); + } + + // check that table deletaion was logged + const tableLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(tableLogsResponse.status, 200); + + const tableLogsRO = JSON.parse(tableLogsResponse.text); + t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); + const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); + for (const key of primaryKeysForDeletion) { + t.is(onlyDeleteLogs.findIndex((log) => log.received_data._id === key._id) >= 0, true); + } }); currentTest = 'DELETE /table/rows/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const primaryKeysForDeletion = [ - { - _id: insertedSearchedIds[0]._id, - }, - { - _id: insertedSearchedIds[9]._id, - }, - { - _id: insertedSearchedIds[31]._id, - }, - ]; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) - .send(primaryKeysForDeletion) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const _deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(getTableRowsResponse.status, 200); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 39); - for (const primaryKey of primaryKeysForDeletion) { - t.is( - rows.findIndex((row) => row._id === primaryKey._id), - -1, - ); - } + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName, insertedSearchedIds } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const primaryKeysForDeletion = [ + { + _id: insertedSearchedIds[0]._id, + }, + { + _id: insertedSearchedIds[9]._id, + }, + { + _id: insertedSearchedIds[31]._id, + }, + ]; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) + .send(primaryKeysForDeletion) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const _deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(getTableRowsResponse.status, 200); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 39); + for (const primaryKey of primaryKeysForDeletion) { + t.is( + rows.findIndex((row) => row._id === primaryKey._id), + -1, + ); + } }); test.serial(`${currentTest} should test connection and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const testConnectionResponse = await request(app.getHttpServer()) - .post('/connection/test/') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse.status, 201); - const { message } = JSON.parse(testConnectionResponse.text); - t.is(message, 'Successfully connected'); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const testConnectionResponse = await request(app.getHttpServer()) + .post('/connection/test/') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse.status, 201); + const { message } = JSON.parse(testConnectionResponse.text); + t.is(message, 'Successfully connected'); }); currentTest = 'GET table/csv/:slug'; test.serial(`${currentTest} should return csv file with table data`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); }); test.serial( - `${currentTest} should return csv file with table data with search, with pagination, with sorting, + `${currentTest} should return csv file with table data with search, with pagination, with sorting, with search and pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { - testTableName, - testTableColumnName, - testEntitiesSeedsCount, - testTableSecondColumnName, - insertedSearchedIds, - } = await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - '_id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post( - `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - }, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { + testTableName, + testTableColumnName, + testEntitiesSeedsCount, + testTableSecondColumnName, + insertedSearchedIds, + } = await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + '_id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post( + `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + }, ); currentTest = 'POST /table/csv/import/:slug'; test.serial(`${currentTest} should import csv file with table data`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - '_id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post( - `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - - function deleteIdColumnsInCSVFile(filePatch: string) { - // eslint-disable-next-line security/detect-non-literal-fs-filename - const fileContent = fs.readFileSync(filePatch).toString(); - const rows = fileContent.split('\n'); - const idColumnIndex = rows[0].split(',').indexOf('_id'); - const newRows = rows.map((row) => { - const columns = row.split(','); - if (columns.length === 1) { - return row; - } - if (idColumnIndex >= 0) { - columns.splice(idColumnIndex, 1); - } - return columns.join(','); - }); - return newRows.join('\n'); - } - - const newFileContent = deleteIdColumnsInCSVFile(downloadedFilePatch); - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, newFileContent); - - const importCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) - .attach('file', downloadedFilePatch) - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - - t.is(importCsvResponse.status, 201); - - //checking that the lines was added - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(getTableRowsResponse.status, 200); - t.is(getTableRowsRO.rows.length, testEntitiesSeedsCount + 2); + const connectionToTestDB = getTestData(mockFactory).mongoDbConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + '_id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post( + `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + + function deleteIdColumnsInCSVFile(filePatch: string) { + // eslint-disable-next-line security/detect-non-literal-fs-filename + const fileContent = fs.readFileSync(filePatch).toString(); + const rows = fileContent.split('\n'); + const idColumnIndex = rows[0].split(',').indexOf('_id'); + const newRows = rows.map((row) => { + const columns = row.split(','); + if (columns.length === 1) { + return row; + } + if (idColumnIndex >= 0) { + columns.splice(idColumnIndex, 1); + } + return columns.join(','); + }); + return newRows.join('\n'); + } + + const newFileContent = deleteIdColumnsInCSVFile(downloadedFilePatch); + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, newFileContent); + + const importCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) + .attach('file', downloadedFilePatch) + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + + t.is(importCsvResponse.status, 201); + + //checking that the lines was added + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(getTableRowsResponse.status, 200); + t.is(getTableRowsRO.rows.length, testEntitiesSeedsCount + 2); }); diff --git a/backend/test/ava-tests/saas-tests/table-mssql-e2e.test.ts b/backend/test/ava-tests/saas-tests/table-mssql-e2e.test.ts index 0d9a9c662..ef1a85075 100644 --- a/backend/test/ava-tests/saas-tests/table-mssql-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/table-mssql-e2e.test.ts @@ -40,3930 +40,3930 @@ const testTables: Array = []; let currentTest; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - await dropTestTables(testTables, connectionToTestMSSQL); - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + await dropTestTables(testTables, connectionToTestMSSQL); + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /connection/tables/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 200); - const getTablesRO = JSON.parse(getTablesResponse.text); - - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.length > 0, true); - - const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); - - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); - t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); - t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); - t.is(getTablesRO[testTableIndex].table, testTableName); - t.is(getTablesRO[testTableIndex].permissions.visibility, true); - t.is(getTablesRO[testTableIndex].permissions.readonly, false); - t.is(getTablesRO[testTableIndex].permissions.add, true); - t.is(getTablesRO[testTableIndex].permissions.delete, true); - t.is(getTablesRO[testTableIndex].permissions.edit, true); - } catch (e) { - console.error(e); - throw e; - } + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 200); + const getTablesRO = JSON.parse(getTablesResponse.text); + + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.length > 0, true); + + const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); + + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); + t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); + t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); + t.is(getTablesRO[testTableIndex].table, testTableName); + t.is(getTablesRO[testTableIndex].permissions.visibility, true); + t.is(getTablesRO[testTableIndex].permissions.readonly, false); + t.is(getTablesRO[testTableIndex].permissions.add, true); + t.is(getTablesRO[testTableIndex].permissions.delete, true); + t.is(getTablesRO[testTableIndex].permissions.edit, true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connectionId not passed in request`, async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = ''; - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = ''; + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connection id is incorrect`, async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = faker.string.uuid(); - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 400); - const { message } = JSON.parse(getTablesResponse.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = faker.string.uuid(); + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 400); + const { message } = JSON.parse(getTablesResponse.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return rows of selected table without search and without pagination`, async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return rows of selected table with search and without pagination`, async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createTableSettingsResponse.status, 201); - - const searchedDescription = '25'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const searchedDescription = '25'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=1, perPage=2`, async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Content-Type', 'application/json') - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=3, perPage=2`, async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 3); - } catch (e) { - console.error(e); - throw e; - } + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 3); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=2`, - async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=3`, - async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by DESC`, - async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - t.is(getTableRowsRO.rows[41].id, 1); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + t.is(getTableRowsRO.rows[41].id, 1); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by ASC`, - async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - t.is(getTableRowsRO.rows[41].id, 42); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + t.is(getTableRowsRO.rows[41].id, 42); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and with pagination and with sorting + `${currentTest} without search and with pagination and with sorting should return all found rows with sorting ports by DESC and with pagination page=1, perPage=2`, - async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, - async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, + async (t) => { + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, - async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 39); - t.is(getTableRowsRO.rows[1].id, 38); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, + async (t) => { + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 39); + t.is(getTableRowsRO.rows[1].id, 38); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting`, - async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and ASC sorting`, - async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and ASC sorting`, - async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '45'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '45'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=10 and DESC sorting and filtering'`, - async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[2].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 10); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[2].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 10); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and with multi filtering`, - async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - createConnectionRO.id = ''; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + createConnectionRO.id = ''; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - createConnectionRO.id = faker.string.uuid(); - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 403); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + createConnectionRO.id = faker.string.uuid(); + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 403); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 400); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 400); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, - async (t) => { - try { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = faker.lorem.words(1); - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTablesRO = JSON.parse(getTableRowsResponse.text); - t.is(getTablesRO.rows.length, 2); - t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTablesRO, 'pagination'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, + async (t) => { + try { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = faker.lorem.words(1); + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTablesRO = JSON.parse(getTableRowsResponse.text); + t.is(getTablesRO.rows.length, 2); + t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTablesRO, 'pagination'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 200); - const getTableStructureRO = JSON.parse(getTableStructure.text); - - t.is(typeof getTableStructureRO, 'object'); - t.is(typeof getTableStructureRO.structure, 'object'); - t.is(getTableStructureRO.structure.length, 5); - - for (const element of getTableStructureRO.structure) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'column_default'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - t.is(Object.hasOwn(element, 'isExcluded'), true); - t.is(Object.hasOwn(element, 'isSearched'), true); - } - - t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); - - for (const element of getTableStructureRO.primaryColumns) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - } - - for (const element of getTableStructureRO.foreignKeys) { - t.is(Object.hasOwn(element, 'referenced_column_name'), true); - t.is(Object.hasOwn(element, 'referenced_table_name'), true); - t.is(Object.hasOwn(element, 'constraint_name'), true); - t.is(Object.hasOwn(element, 'column_name'), true); - } + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 200); + const getTableStructureRO = JSON.parse(getTableStructure.text); + + t.is(typeof getTableStructureRO, 'object'); + t.is(typeof getTableStructureRO.structure, 'object'); + t.is(getTableStructureRO.structure.length, 5); + + for (const element of getTableStructureRO.structure) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'column_default'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + t.is(Object.hasOwn(element, 'isExcluded'), true); + t.is(Object.hasOwn(element, 'isSearched'), true); + } + + t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); + + for (const element of getTableStructureRO.primaryColumns) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + } + + for (const element of getTableStructureRO.foreignKeys) { + t.is(Object.hasOwn(element, 'referenced_column_name'), true); + t.is(Object.hasOwn(element, 'referenced_table_name'), true); + t.is(Object.hasOwn(element, 'constraint_name'), true); + t.is(Object.hasOwn(element, 'column_name'), true); + } }); test.serial(`${currentTest} should throw an exception whe connection id not passed in request`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 404); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 404); }); test.serial(`${currentTest} should throw an exception whe connection id passed in request id incorrect`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = faker.string.uuid(); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 403); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = faker.string.uuid(); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 403); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest}should throw an exception when tableName not passed in request`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = faker.lorem.words(1); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = faker.lorem.words(1); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should add row in table and return result`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addRowInTableRO = JSON.parse(addRowInTableResponse.text); - t.is(addRowInTableResponse.status, 201); - - t.is(Object.hasOwn(addRowInTableRO, 'row'), true); - t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); - t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 43); - t.is(rows[42][testTableColumnName], row[testTableColumnName]); - t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); - t.is(rows[42].id, rows[41].id + 1); - - // check that rows adding was logged - - const getLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getLogsResponse.status, 200); - const getLogsRO = JSON.parse(getLogsResponse.text); - t.is(Object.hasOwn(getLogsRO, 'logs'), true); - t.is(Object.hasOwn(getLogsRO, 'pagination'), true); - t.is(getLogsRO.logs.length > 0, true); - const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); - t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); - t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, 43); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addRowInTableRO = JSON.parse(addRowInTableResponse.text); + t.is(addRowInTableResponse.status, 201); + + t.is(Object.hasOwn(addRowInTableRO, 'row'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 43); + t.is(rows[42][testTableColumnName], row[testTableColumnName]); + t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); + t.is(rows[42].id, rows[41].id + 1); + + // check that rows adding was logged + + const getLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getLogsResponse.status, 200); + const getLogsRO = JSON.parse(getLogsResponse.text); + t.is(Object.hasOwn(getLogsRO, 'logs'), true); + t.is(Object.hasOwn(getLogsRO, 'pagination'), true); + t.is(getLogsRO.logs.length > 0, true); + const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); + t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); + t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, 43); }); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const fakeConnectionId = ''; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 404); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const fakeConnectionId = ''; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 404); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name is not passed in request`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when row is not passed in request`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.PARAMETER_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.PARAMETER_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); currentTest = 'PUT /table/row/:slug'; test.serial(`${currentTest} should update row in table and return result`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 200); - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); - t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was updated - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - const updateRowIndex = rows.map((row) => row.id).indexOf(1); - t.is(rows.length, 42); - t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); - t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 200); + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); + t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was updated + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + const updateRowIndex = rows.map((row) => row.id).indexOf(1); + t.is(rows.length, 42); + t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); + t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = ''; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 404); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = ''; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 404); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 403); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 403); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/update/:connectionId'; test.serial(`${currentTest} should update multiple rows and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToTestMSSQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const requestData = { - primaryKeys: [{ id: 1 }, { id: 2 }], - newValues: { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(requestData)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(updateRowInTableResponse.status, 200); - t.is(updateRowInTableRO.success, true); - - // check that the rows were updated - const firstRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const firstRow = JSON.parse(firstRowResponse.text); - t.is(firstRowResponse.status, 200); - t.is(firstRow.row[testTableColumnName], fakeName); - t.is(firstRow.row[testTableSecondColumnName], fakeMail); - - const secondRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const secondRow = JSON.parse(secondRowResponse.text); - t.is(secondRowResponse.status, 200); - t.is(secondRow.row[testTableColumnName], fakeName); - t.is(secondRow.row[testTableSecondColumnName], fakeMail); + const connectionToTestDB = getTestData(mockFactory).connectionToTestMSSQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const requestData = { + primaryKeys: [{ id: 1 }, { id: 2 }], + newValues: { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(requestData)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(updateRowInTableResponse.status, 200); + t.is(updateRowInTableRO.success, true); + + // check that the rows were updated + const firstRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const firstRow = JSON.parse(firstRowResponse.text); + t.is(firstRowResponse.status, 200); + t.is(firstRow.row[testTableColumnName], fakeName); + t.is(firstRow.row[testTableSecondColumnName], fakeMail); + + const secondRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const secondRow = JSON.parse(secondRowResponse.text); + t.is(secondRowResponse.status, 200); + t.is(secondRow.row[testTableColumnName], fakeName); + t.is(secondRow.row[testTableSecondColumnName], fakeMail); }); currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 41); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, true); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 41); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, true); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 404); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 404); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = faker.string.uuid(); - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 403); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = faker.string.uuid(); + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 403); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - t.is(deleteRowInTableResponse.status, 400); - t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + t.is(deleteRowInTableResponse.status, 400); + t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 200); - const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); - t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); - t.is(typeof foundRowInTableRO.row, 'object'); - t.is(typeof foundRowInTableRO.structure, 'object'); - t.is(typeof foundRowInTableRO.primaryColumns, 'object'); - t.is(typeof foundRowInTableRO.readonly_fields, 'object'); - t.is(typeof foundRowInTableRO.foreignKeys, 'object'); - t.is(foundRowInTableRO.row.id, 1); - t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); - t.is(Object.keys(foundRowInTableRO.row).length, 5); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 200); + const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); + t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); + t.is(typeof foundRowInTableRO.row, 'object'); + t.is(typeof foundRowInTableRO.structure, 'object'); + t.is(typeof foundRowInTableRO.primaryColumns, 'object'); + t.is(typeof foundRowInTableRO.readonly_fields, 'object'); + t.is(typeof foundRowInTableRO.foreignKeys, 'object'); + t.is(foundRowInTableRO.row.id, 1); + t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); + t.is(Object.keys(foundRowInTableRO.row).length, 5); }); test.serial(`${currentTest} should throw an exception, when connection id is not passed in request`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const idForSearch = 1; - createConnectionRO.id = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 404); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const idForSearch = 1; + createConnectionRO.id = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 404); }); test.serial( - `${currentTest} should throw an exception, when connection id passed in request is incorrect`, - async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - createConnectionRO.id = faker.string.uuid(); - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 403); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - }, + `${currentTest} should throw an exception, when connection id passed in request is incorrect`, + async (t) => { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + createConnectionRO.id = faker.string.uuid(); + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 403); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + }, ); test.serial(`${currentTest} should throw an exception, when tableName in not passed in request`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception, when tableName passed in request is incorrect`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception, when primary key is not passed in request`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, - async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, + async (t) => { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, - async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1000000; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, + async (t) => { + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1000000; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/delete/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const primaryKeysForDeletion: Array> = [ - { - id: 1, - }, - { - id: 10, - }, - { - id: 32, - }, - ]; - const deleteRowsInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) - .send(primaryKeysForDeletion) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowsInTableResponse.status, 200); - const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - // check that lines was deleted - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); - - for (const key of primaryKeysForDeletion) { - t.is( - rows.findIndex((row) => row.id === key.id), - -1, - ); - } - - // check that table deletaion was logged - const tableLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(tableLogsResponse.status, 200); - - const tableLogsRO = JSON.parse(tableLogsResponse.text); - t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); - const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); - for (const key of primaryKeysForDeletion) { - t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); - } + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const primaryKeysForDeletion: Array> = [ + { + id: 1, + }, + { + id: 10, + }, + { + id: 32, + }, + ]; + const deleteRowsInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) + .send(primaryKeysForDeletion) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowsInTableResponse.status, 200); + const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + // check that lines was deleted + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); + + for (const key of primaryKeysForDeletion) { + t.is( + rows.findIndex((row) => row.id === key.id), + -1, + ); + } + + // check that table deletaion was logged + const tableLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(tableLogsResponse.status, 200); + + const tableLogsRO = JSON.parse(tableLogsResponse.text); + t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); + const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); + for (const key of primaryKeysForDeletion) { + t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); + } }); test.serial(`${currentTest} should test connection and return result`, async (t) => { - const { connectionToTestMSSQL } = getTestData(mockFactory); - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const testConnectionResponse = await request(app.getHttpServer()) - .post('/connection/test/') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse.status, 201); - const { message } = JSON.parse(testConnectionResponse.text); - t.is(message, 'Successfully connected'); + const { connectionToTestMSSQL } = getTestData(mockFactory); + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const testConnectionResponse = await request(app.getHttpServer()) + .post('/connection/test/') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse.status, 201); + const { message } = JSON.parse(testConnectionResponse.text); + t.is(message, 'Successfully connected'); }); currentTest = 'GET table/csv/:slug'; test.serial(`${currentTest} should return csv file with table data`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToTestMSSQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); + const connectionToTestDB = getTestData(mockFactory).connectionToTestMSSQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); }); test.serial( - `${currentTest} should return csv file with table data with search, with pagination, with sorting, + `${currentTest} should return csv file with table data with search, with pagination, with sorting, with search and pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToTestMSSQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post( - `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - }, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToTestMSSQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post( + `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + }, ); currentTest = 'POST /table/csv/import/:slug'; test.serial(`${currentTest} should import csv file with table data`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToTestMSSQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post( - `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - - function deleteIdColumnsInCSVFile(filePatch: string) { - // eslint-disable-next-line security/detect-non-literal-fs-filename - const fileContent = fs.readFileSync(filePatch).toString(); - const rows = fileContent.split('\n'); - const newRows = rows.map((row) => { - const columns = row.split(','); - if (columns.length === 1) { - return row; - } - columns.shift(); - return columns.join(','); - }); - return newRows.join('\n'); - } - - const newFileContent = deleteIdColumnsInCSVFile(downloadedFilePatch); - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, newFileContent); - - const importCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) - .attach('file', downloadedFilePatch) - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - - t.is(importCsvResponse.status, 201); - - //checking that the lines was added - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(getTableRowsResponse.status, 200); - const addedRows = getTableRowsRO.rows.filter((row: Record) => row.id > testEntitiesSeedsCount); - t.is(addedRows.length, 2); + const connectionToTestDB = getTestData(mockFactory).connectionToTestMSSQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post( + `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + + function deleteIdColumnsInCSVFile(filePatch: string) { + // eslint-disable-next-line security/detect-non-literal-fs-filename + const fileContent = fs.readFileSync(filePatch).toString(); + const rows = fileContent.split('\n'); + const newRows = rows.map((row) => { + const columns = row.split(','); + if (columns.length === 1) { + return row; + } + columns.shift(); + return columns.join(','); + }); + return newRows.join('\n'); + } + + const newFileContent = deleteIdColumnsInCSVFile(downloadedFilePatch); + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, newFileContent); + + const importCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) + .attach('file', downloadedFilePatch) + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + + t.is(importCsvResponse.status, 201); + + //checking that the lines was added + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(getTableRowsResponse.status, 200); + const addedRows = getTableRowsRO.rows.filter((row: Record) => row.id > testEntitiesSeedsCount); + t.is(addedRows.length, 2); }); diff --git a/backend/test/ava-tests/saas-tests/table-mssql-schema-e2e.test.ts b/backend/test/ava-tests/saas-tests/table-mssql-schema-e2e.test.ts index 564064ac8..858fa9d17 100644 --- a/backend/test/ava-tests/saas-tests/table-mssql-schema-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/table-mssql-schema-e2e.test.ts @@ -32,3694 +32,3694 @@ const testTables: Array = []; let currentTest; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after('Drop test tables', async () => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - await dropTestTables(testTables, connectionToTestMSSQL); - await Cacher.clearAllCache(); - await app.close(); - } catch (_e) {} + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + await dropTestTables(testTables, connectionToTestMSSQL); + await Cacher.clearAllCache(); + await app.close(); + } catch (_e) {} }); currentTest = 'GET /connection/tables/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 200); - const getTablesRO = JSON.parse(getTablesResponse.text); - - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.length > 0, true); - - const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); - - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); - t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); - t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); - t.is(getTablesRO[testTableIndex].table, testTableName); - t.is(getTablesRO[testTableIndex].permissions.visibility, true); - t.is(getTablesRO[testTableIndex].permissions.readonly, false); - t.is(getTablesRO[testTableIndex].permissions.add, true); - t.is(getTablesRO[testTableIndex].permissions.delete, true); - t.is(getTablesRO[testTableIndex].permissions.edit, true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 200); + const getTablesRO = JSON.parse(getTablesResponse.text); + + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.length > 0, true); + + const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); + + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); + t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); + t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); + t.is(getTablesRO[testTableIndex].table, testTableName); + t.is(getTablesRO[testTableIndex].permissions.visibility, true); + t.is(getTablesRO[testTableIndex].permissions.readonly, false); + t.is(getTablesRO[testTableIndex].permissions.add, true); + t.is(getTablesRO[testTableIndex].permissions.delete, true); + t.is(getTablesRO[testTableIndex].permissions.edit, true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connectionId not passed in request`, async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = ''; - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = ''; + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connection id is incorrect`, async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = faker.string.uuid(); - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 400); - const { message } = JSON.parse(getTablesResponse.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = faker.string.uuid(); + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 400); + const { message } = JSON.parse(getTablesResponse.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return rows of selected table without search and without pagination`, async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return rows of selected table with search and without pagination`, async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createTableSettingsResponse.status, 201); - - const searchedDescription = '25'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const searchedDescription = '25'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=1, perPage=2`, async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Content-Type', 'application/json') - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=3, perPage=2`, async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 3); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 3); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=2`, - async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=3`, - async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by DESC`, - async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - t.is(getTableRowsRO.rows[41].id, 1); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + t.is(getTableRowsRO.rows[41].id, 1); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by ASC`, - async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - t.is(getTableRowsRO.rows[41].id, 42); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + t.is(getTableRowsRO.rows[41].id, 42); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and with pagination and with sorting + `${currentTest} without search and with pagination and with sorting should return all found rows with sorting ports by DESC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, + async (t) => { + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, - async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 39); - t.is(getTableRowsRO.rows[1].id, 38); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, + async (t) => { + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 39); + t.is(getTableRowsRO.rows[1].id, 38); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '45'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '45'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=10 and DESC sorting and filtering'`, - async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[2].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 10); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[2].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 10); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and with multi filtering`, - async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - createConnectionRO.id = ''; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + createConnectionRO.id = ''; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - createConnectionRO.id = faker.string.uuid(); - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 403); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + createConnectionRO.id = faker.string.uuid(); + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 403); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 400); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 400); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, - async (t) => { - try { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = faker.lorem.words(1); - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTablesRO = JSON.parse(getTableRowsResponse.text); - t.is(getTablesRO.rows.length, 2); - t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTablesRO, 'pagination'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, + async (t) => { + try { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = faker.lorem.words(1); + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTablesRO = JSON.parse(getTableRowsResponse.text); + t.is(getTablesRO.rows.length, 2); + t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTablesRO, 'pagination'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 200); - const getTableStructureRO = JSON.parse(getTableStructure.text); - - t.is(typeof getTableStructureRO, 'object'); - t.is(typeof getTableStructureRO.structure, 'object'); - t.is(getTableStructureRO.structure.length, 5); - - for (const element of getTableStructureRO.structure) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'column_default'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - t.is(Object.hasOwn(element, 'isExcluded'), true); - t.is(Object.hasOwn(element, 'isSearched'), true); - } - - t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); - - for (const element of getTableStructureRO.primaryColumns) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - } - - for (const element of getTableStructureRO.foreignKeys) { - t.is(Object.hasOwn(element, 'referenced_column_name'), true); - t.is(Object.hasOwn(element, 'referenced_table_name'), true); - t.is(Object.hasOwn(element, 'constraint_name'), true); - t.is(Object.hasOwn(element, 'column_name'), true); - } + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 200); + const getTableStructureRO = JSON.parse(getTableStructure.text); + + t.is(typeof getTableStructureRO, 'object'); + t.is(typeof getTableStructureRO.structure, 'object'); + t.is(getTableStructureRO.structure.length, 5); + + for (const element of getTableStructureRO.structure) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'column_default'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + t.is(Object.hasOwn(element, 'isExcluded'), true); + t.is(Object.hasOwn(element, 'isSearched'), true); + } + + t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); + + for (const element of getTableStructureRO.primaryColumns) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + } + + for (const element of getTableStructureRO.foreignKeys) { + t.is(Object.hasOwn(element, 'referenced_column_name'), true); + t.is(Object.hasOwn(element, 'referenced_table_name'), true); + t.is(Object.hasOwn(element, 'constraint_name'), true); + t.is(Object.hasOwn(element, 'column_name'), true); + } }); test.serial(`${currentTest} should throw an exception whe connection id not passed in request`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 404); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 404); }); test.serial(`${currentTest} should throw an exception whe connection id passed in request id incorrect`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = faker.string.uuid(); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 403); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = faker.string.uuid(); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 403); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest}should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = faker.lorem.words(1); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = faker.lorem.words(1); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should add row in table and return result`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addRowInTableRO = JSON.parse(addRowInTableResponse.text); - t.is(addRowInTableResponse.status, 201); - - t.is(Object.hasOwn(addRowInTableRO, 'row'), true); - t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); - t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 43); - t.is(rows[42][testTableColumnName], row[testTableColumnName]); - t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); - t.is(rows[42].id, rows[41].id + 1); - - // check that rows adding was logged - - const getLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getLogsResponse.status, 200); - const getLogsRO = JSON.parse(getLogsResponse.text); - t.is(Object.hasOwn(getLogsRO, 'logs'), true); - t.is(Object.hasOwn(getLogsRO, 'pagination'), true); - t.is(getLogsRO.logs.length > 0, true); - const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); - t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); - t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, 43); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addRowInTableRO = JSON.parse(addRowInTableResponse.text); + t.is(addRowInTableResponse.status, 201); + + t.is(Object.hasOwn(addRowInTableRO, 'row'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 43); + t.is(rows[42][testTableColumnName], row[testTableColumnName]); + t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); + t.is(rows[42].id, rows[41].id + 1); + + // check that rows adding was logged + + const getLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getLogsResponse.status, 200); + const getLogsRO = JSON.parse(getLogsResponse.text); + t.is(Object.hasOwn(getLogsRO, 'logs'), true); + t.is(Object.hasOwn(getLogsRO, 'pagination'), true); + t.is(getLogsRO.logs.length > 0, true); + const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); + t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); + t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, 43); }); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const fakeConnectionId = ''; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 404); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const fakeConnectionId = ''; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 404); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name is not passed in request`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when row is not passed in request`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.PARAMETER_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.PARAMETER_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); currentTest = 'PUT /table/row/:slug'; test.serial(`${currentTest} should update row in table and return result`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 200); - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); - t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was updated - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - const updateRowIndex = rows.map((row) => row.id).indexOf(1); - t.is(rows.length, 42); - t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); - t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 200); + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); + t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was updated + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + const updateRowIndex = rows.map((row) => row.id).indexOf(1); + t.is(rows.length, 42); + t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); + t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = ''; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 404); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = ''; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 404); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 403); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 403); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/update/:connectionId'; test.serial(`${currentTest} should update multiple rows and return result`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const requestData = { - primaryKeys: [{ id: 1 }, { id: 2 }], - newValues: { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(requestData)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(updateRowInTableResponse.status, 200); - t.is(updateRowInTableRO.success, true); - - // check that the rows were updated - const firstRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const firstRow = JSON.parse(firstRowResponse.text); - t.is(firstRowResponse.status, 200); - t.is(firstRow.row[testTableColumnName], fakeName); - t.is(firstRow.row[testTableSecondColumnName], fakeMail); - - const secondRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const secondRow = JSON.parse(secondRowResponse.text); - t.is(secondRowResponse.status, 200); - t.is(secondRow.row[testTableColumnName], fakeName); - t.is(secondRow.row[testTableSecondColumnName], fakeMail); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const requestData = { + primaryKeys: [{ id: 1 }, { id: 2 }], + newValues: { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(requestData)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(updateRowInTableResponse.status, 200); + t.is(updateRowInTableRO.success, true); + + // check that the rows were updated + const firstRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const firstRow = JSON.parse(firstRowResponse.text); + t.is(firstRowResponse.status, 200); + t.is(firstRow.row[testTableColumnName], fakeName); + t.is(firstRow.row[testTableSecondColumnName], fakeMail); + + const secondRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const secondRow = JSON.parse(secondRowResponse.text); + t.is(secondRowResponse.status, 200); + t.is(secondRow.row[testTableColumnName], fakeName); + t.is(secondRow.row[testTableSecondColumnName], fakeMail); }); currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 41); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, true); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 41); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, true); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 404); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 404); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = faker.string.uuid(); - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 403); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = faker.string.uuid(); + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 403); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - t.is(deleteRowInTableResponse.status, 400); - t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + t.is(deleteRowInTableResponse.status, 400); + t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 200); - const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); - t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); - t.is(typeof foundRowInTableRO.row, 'object'); - t.is(typeof foundRowInTableRO.structure, 'object'); - t.is(typeof foundRowInTableRO.primaryColumns, 'object'); - t.is(typeof foundRowInTableRO.readonly_fields, 'object'); - t.is(typeof foundRowInTableRO.foreignKeys, 'object'); - t.is(foundRowInTableRO.row.id, 1); - t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); - t.is(Object.keys(foundRowInTableRO.row).length, 5); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 200); + const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); + t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); + t.is(typeof foundRowInTableRO.row, 'object'); + t.is(typeof foundRowInTableRO.structure, 'object'); + t.is(typeof foundRowInTableRO.primaryColumns, 'object'); + t.is(typeof foundRowInTableRO.readonly_fields, 'object'); + t.is(typeof foundRowInTableRO.foreignKeys, 'object'); + t.is(foundRowInTableRO.row.id, 1); + t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); + t.is(Object.keys(foundRowInTableRO.row).length, 5); }); test.serial(`${currentTest} should throw an exception, when connection id is not passed in request`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const idForSearch = 1; - createConnectionRO.id = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 404); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const idForSearch = 1; + createConnectionRO.id = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 404); }); test.serial( - `${currentTest} should throw an exception, when connection id passed in request is incorrect`, - async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - createConnectionRO.id = faker.string.uuid(); - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 403); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - }, + `${currentTest} should throw an exception, when connection id passed in request is incorrect`, + async (t) => { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + createConnectionRO.id = faker.string.uuid(); + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 403); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + }, ); test.serial(`${currentTest} should throw an exception, when tableName in not passed in request`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception, when tableName passed in request is incorrect`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception, when primary key is not passed in request`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, - async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, + async (t) => { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, - async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1000000; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, + async (t) => { + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1000000; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/delete/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTableForMSSQLWithChema(connectionToTestMSSQL); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const primaryKeysForDeletion: Array> = [ - { - id: 1, - }, - { - id: 10, - }, - { - id: 32, - }, - ]; - const deleteRowsInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) - .send(primaryKeysForDeletion) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowsInTableResponse.status, 200); - const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - // check that lines was deleted - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); - - for (const key of primaryKeysForDeletion) { - t.is( - rows.findIndex((row) => row.id === key.id), - -1, - ); - } - - // check that table deletaion was logged - const tableLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(tableLogsResponse.status, 200); - - const tableLogsRO = JSON.parse(tableLogsResponse.text); - t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); - const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); - for (const key of primaryKeysForDeletion) { - t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); - } + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTableForMSSQLWithChema(connectionToTestMSSQL); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const primaryKeysForDeletion: Array> = [ + { + id: 1, + }, + { + id: 10, + }, + { + id: 32, + }, + ]; + const deleteRowsInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) + .send(primaryKeysForDeletion) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowsInTableResponse.status, 200); + const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + // check that lines was deleted + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); + + for (const key of primaryKeysForDeletion) { + t.is( + rows.findIndex((row) => row.id === key.id), + -1, + ); + } + + // check that table deletaion was logged + const tableLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(tableLogsResponse.status, 200); + + const tableLogsRO = JSON.parse(tableLogsResponse.text); + t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); + const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); + for (const key of primaryKeysForDeletion) { + t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); + } }); test.serial(`${currentTest} should test connection and return result`, async (t) => { - const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const testConnectionResponse = await request(app.getHttpServer()) - .post('/connection/test/') - .send(connectionToTestMSSQL) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse.status, 201); - const { message } = JSON.parse(testConnectionResponse.text); - t.is(message, 'Successfully connected'); + const connectionToTestMSSQL = getTestData(mockFactory).connectionToTestMSSQLSchemaInDocker; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const testConnectionResponse = await request(app.getHttpServer()) + .post('/connection/test/') + .send(connectionToTestMSSQL) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse.status, 201); + const { message } = JSON.parse(testConnectionResponse.text); + t.is(message, 'Successfully connected'); }); diff --git a/backend/test/ava-tests/saas-tests/table-mysql-e2e.test.ts b/backend/test/ava-tests/saas-tests/table-mysql-e2e.test.ts index 2a5bd0578..1c52edc86 100644 --- a/backend/test/ava-tests/saas-tests/table-mysql-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/table-mysql-e2e.test.ts @@ -40,3933 +40,3933 @@ const testTables: Array = []; let currentTest; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - await dropTestTables(testTables, connectionToTestDB); - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + await dropTestTables(testTables, connectionToTestDB); + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /connection/tables/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 200); - const getTablesRO = JSON.parse(getTablesResponse.text); - - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.length > 0, true); - - const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); - - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); - t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); - t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); - t.is(getTablesRO[testTableIndex].table, testTableName); - t.is(getTablesRO[testTableIndex].permissions.visibility, true); - t.is(getTablesRO[testTableIndex].permissions.readonly, false); - t.is(getTablesRO[testTableIndex].permissions.add, true); - t.is(getTablesRO[testTableIndex].permissions.delete, true); - t.is(getTablesRO[testTableIndex].permissions.edit, true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 200); + const getTablesRO = JSON.parse(getTablesResponse.text); + + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.length > 0, true); + + const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); + + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); + t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); + t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); + t.is(getTablesRO[testTableIndex].table, testTableName); + t.is(getTablesRO[testTableIndex].permissions.visibility, true); + t.is(getTablesRO[testTableIndex].permissions.readonly, false); + t.is(getTablesRO[testTableIndex].permissions.add, true); + t.is(getTablesRO[testTableIndex].permissions.delete, true); + t.is(getTablesRO[testTableIndex].permissions.edit, true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connectionId not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = ''; - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = ''; + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connection id is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = faker.string.uuid(); - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 400); - const { message } = JSON.parse(getTablesResponse.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = faker.string.uuid(); + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 400); + const { message } = JSON.parse(getTablesResponse.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return rows of selected table without search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return rows of selected table with search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createTableSettingsResponse.status, 201); - - const searchedDescription = '25'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const searchedDescription = '25'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=1, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Content-Type', 'application/json') - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=3, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 3); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 3); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by DESC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - t.is(getTableRowsRO.rows[41].id, 1); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + t.is(getTableRowsRO.rows[41].id, 1); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by ASC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - t.is(getTableRowsRO.rows[41].id, 42); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + t.is(getTableRowsRO.rows[41].id, 42); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and with pagination and with sorting + `${currentTest} without search and with pagination and with sorting should return all found rows with sorting ports by DESC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 39); - t.is(getTableRowsRO.rows[1].id, 38); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 39); + t.is(getTableRowsRO.rows[1].id, 38); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '45'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '45'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=10 and DESC sorting and filtering'`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[2].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 10); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[2].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 10); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and with multi filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - createConnectionRO.id = ''; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + createConnectionRO.id = ''; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - createConnectionRO.id = faker.string.uuid(); - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 403); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + createConnectionRO.id = faker.string.uuid(); + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 403); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 400); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 400); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = faker.lorem.words(1); - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTablesRO = JSON.parse(getTableRowsResponse.text); - t.is(getTablesRO.rows.length, 2); - t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTablesRO, 'pagination'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = faker.lorem.words(1); + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTablesRO = JSON.parse(getTableRowsResponse.text); + t.is(getTablesRO.rows.length, 2); + t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTablesRO, 'pagination'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 200); - const getTableStructureRO = JSON.parse(getTableStructure.text); - - t.is(typeof getTableStructureRO, 'object'); - t.is(typeof getTableStructureRO.structure, 'object'); - t.is(getTableStructureRO.structure.length, 5); - - for (const element of getTableStructureRO.structure) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'column_default'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - t.is(Object.hasOwn(element, 'isExcluded'), true); - t.is(Object.hasOwn(element, 'isSearched'), true); - } - - t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); - - for (const element of getTableStructureRO.primaryColumns) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - } - - for (const element of getTableStructureRO.foreignKeys) { - t.is(Object.hasOwn(element, 'referenced_column_name'), true); - t.is(Object.hasOwn(element, 'referenced_table_name'), true); - t.is(Object.hasOwn(element, 'constraint_name'), true); - t.is(Object.hasOwn(element, 'column_name'), true); - } + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 200); + const getTableStructureRO = JSON.parse(getTableStructure.text); + + t.is(typeof getTableStructureRO, 'object'); + t.is(typeof getTableStructureRO.structure, 'object'); + t.is(getTableStructureRO.structure.length, 5); + + for (const element of getTableStructureRO.structure) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'column_default'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + t.is(Object.hasOwn(element, 'isExcluded'), true); + t.is(Object.hasOwn(element, 'isSearched'), true); + } + + t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); + + for (const element of getTableStructureRO.primaryColumns) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + } + + for (const element of getTableStructureRO.foreignKeys) { + t.is(Object.hasOwn(element, 'referenced_column_name'), true); + t.is(Object.hasOwn(element, 'referenced_table_name'), true); + t.is(Object.hasOwn(element, 'constraint_name'), true); + t.is(Object.hasOwn(element, 'column_name'), true); + } }); test.serial(`${currentTest} should throw an exception whe connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 404); }); test.serial(`${currentTest} should throw an exception whe connection id passed in request id incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = faker.string.uuid(); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 403); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = faker.string.uuid(); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 403); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest}should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = faker.lorem.words(1); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getStructureRO = JSON.parse(getTableStructure.text); - t.is(getTableStructure.status, 400); - t.is(getStructureRO.message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = faker.lorem.words(1); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getStructureRO = JSON.parse(getTableStructure.text); + t.is(getTableStructure.status, 400); + t.is(getStructureRO.message, Messages.TABLE_NOT_FOUND); }); currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should add row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addRowInTableRO = JSON.parse(addRowInTableResponse.text); - t.is(addRowInTableResponse.status, 201); - - t.is(Object.hasOwn(addRowInTableRO, 'row'), true); - t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); - t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 43); - t.is(rows[42][testTableColumnName], row[testTableColumnName]); - t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); - t.is(rows[42].id, rows[41].id + 1); - - // check that rows adding was logged - - const getLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getLogsResponse.status, 200); - const getLogsRO = JSON.parse(getLogsResponse.text); - t.is(Object.hasOwn(getLogsRO, 'logs'), true); - t.is(Object.hasOwn(getLogsRO, 'pagination'), true); - t.is(getLogsRO.logs.length > 0, true); - const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); - t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); - t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, 43); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addRowInTableRO = JSON.parse(addRowInTableResponse.text); + t.is(addRowInTableResponse.status, 201); + + t.is(Object.hasOwn(addRowInTableRO, 'row'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 43); + t.is(rows[42][testTableColumnName], row[testTableColumnName]); + t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); + t.is(rows[42].id, rows[41].id + 1); + + // check that rows adding was logged + + const getLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getLogsResponse.status, 200); + const getLogsRO = JSON.parse(getLogsResponse.text); + t.is(Object.hasOwn(getLogsRO, 'logs'), true); + t.is(Object.hasOwn(getLogsRO, 'pagination'), true); + t.is(getLogsRO.logs.length > 0, true); + const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); + t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); + t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, 43); }); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const fakeConnectionId = ''; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 404); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const fakeConnectionId = ''; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 404); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when row is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.PARAMETER_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.PARAMETER_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); currentTest = 'PUT /table/row/:slug'; test.serial(`${currentTest} should update row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 200); - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); - t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was updated - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - const updateRowIndex = rows.map((row) => row.id).indexOf(1); - t.is(rows.length, 42); - t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); - t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 200); + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); + t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was updated + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + const updateRowIndex = rows.map((row) => row.id).indexOf(1); + t.is(rows.length, 42); + t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); + t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = ''; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = ''; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 404); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 403); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 403); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/update/:connectionId'; test.serial(`${currentTest} should update multiple rows and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const requestData = { - primaryKeys: [{ id: 1 }, { id: 2 }], - newValues: { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(requestData)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(updateRowInTableResponse.status, 200); - t.is(updateRowInTableRO.success, true); - - // check that the rows were updated - const firstRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const firstRow = JSON.parse(firstRowResponse.text); - t.is(firstRowResponse.status, 200); - t.is(firstRow.row[testTableColumnName], fakeName); - t.is(firstRow.row[testTableSecondColumnName], fakeMail); - - const secondRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const secondRow = JSON.parse(secondRowResponse.text); - t.is(secondRowResponse.status, 200); - t.is(secondRow.row[testTableColumnName], fakeName); - t.is(secondRow.row[testTableSecondColumnName], fakeMail); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const requestData = { + primaryKeys: [{ id: 1 }, { id: 2 }], + newValues: { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(requestData)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(updateRowInTableResponse.status, 200); + t.is(updateRowInTableRO.success, true); + + // check that the rows were updated + const firstRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const firstRow = JSON.parse(firstRowResponse.text); + t.is(firstRowResponse.status, 200); + t.is(firstRow.row[testTableColumnName], fakeName); + t.is(firstRow.row[testTableSecondColumnName], fakeMail); + + const secondRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const secondRow = JSON.parse(secondRowResponse.text); + t.is(secondRowResponse.status, 200); + t.is(secondRow.row[testTableColumnName], fakeName); + t.is(secondRow.row[testTableSecondColumnName], fakeMail); }); currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 41); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, true); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 41); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, true); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 404); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 404); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = faker.string.uuid(); - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 403); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = faker.string.uuid(); + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 403); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - t.is(deleteRowInTableResponse.status, 400); - t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + t.is(deleteRowInTableResponse.status, 400); + t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} found row`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 200); - const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); - t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); - t.is(typeof foundRowInTableRO.row, 'object'); - t.is(typeof foundRowInTableRO.structure, 'object'); - t.is(typeof foundRowInTableRO.primaryColumns, 'object'); - t.is(typeof foundRowInTableRO.readonly_fields, 'object'); - t.is(typeof foundRowInTableRO.foreignKeys, 'object'); - t.is(foundRowInTableRO.row.id, 1); - t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); - t.is(Object.keys(foundRowInTableRO.row).length, 5); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 200); + const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); + t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); + t.is(typeof foundRowInTableRO.row, 'object'); + t.is(typeof foundRowInTableRO.structure, 'object'); + t.is(typeof foundRowInTableRO.primaryColumns, 'object'); + t.is(typeof foundRowInTableRO.readonly_fields, 'object'); + t.is(typeof foundRowInTableRO.foreignKeys, 'object'); + t.is(foundRowInTableRO.row.id, 1); + t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); + t.is(Object.keys(foundRowInTableRO.row).length, 5); }); test.serial(`${currentTest} should throw an exception, when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const idForSearch = 1; - createConnectionRO.id = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const idForSearch = 1; + createConnectionRO.id = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 404); }); test.serial( - `${currentTest} should throw an exception, when connection id passed in request is incorrect`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - createConnectionRO.id = faker.string.uuid(); - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 403); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - }, + `${currentTest} should throw an exception, when connection id passed in request is incorrect`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + createConnectionRO.id = faker.string.uuid(); + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 403); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + }, ); test.serial(`${currentTest} should throw an exception, when tableName in not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception, when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception, when primary key is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1000000; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1000000; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/delete/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const primaryKeysForDeletion: Array> = [ - { - id: 1, - }, - { - id: 10, - }, - { - id: 32, - }, - ]; - const deleteRowsInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) - .send(primaryKeysForDeletion) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowsInTableResponse.status, 200); - const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - // check that lines was deleted - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); - - for (const key of primaryKeysForDeletion) { - t.is( - rows.findIndex((row) => row.id === key.id), - -1, - ); - } - - // check that table deletaion was logged - const tableLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(tableLogsResponse.status, 200); - - const tableLogsRO = JSON.parse(tableLogsResponse.text); - t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); - const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); - for (const key of primaryKeysForDeletion) { - t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); - } + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const primaryKeysForDeletion: Array> = [ + { + id: 1, + }, + { + id: 10, + }, + { + id: 32, + }, + ]; + const deleteRowsInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) + .send(primaryKeysForDeletion) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowsInTableResponse.status, 200); + const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + // check that lines was deleted + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); + + for (const key of primaryKeysForDeletion) { + t.is( + rows.findIndex((row) => row.id === key.id), + -1, + ); + } + + // check that table deletaion was logged + const tableLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(tableLogsResponse.status, 200); + + const tableLogsRO = JSON.parse(tableLogsResponse.text); + t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); + const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); + for (const key of primaryKeysForDeletion) { + t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); + } }); test.serial(`${currentTest} should test connection and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const testConnectionResponse = await request(app.getHttpServer()) - .post('/connection/test/') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse.status, 201); - const { message } = JSON.parse(testConnectionResponse.text); - t.is(message, 'Successfully connected'); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const testConnectionResponse = await request(app.getHttpServer()) + .post('/connection/test/') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse.status, 201); + const { message } = JSON.parse(testConnectionResponse.text); + t.is(message, 'Successfully connected'); }); currentTest = 'GET table/csv/:slug'; test.serial(`${currentTest} should return csv file with table data`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); }); test.serial( - `${currentTest} should return csv file with table data with search, with pagination, with sorting, + `${currentTest} should return csv file with table data with search, with pagination, with sorting, with search and pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post( - `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - }, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post( + `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + }, ); currentTest = 'POST /table/csv/import/:slug'; test.serial(`${currentTest} should import csv file with table data`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post( - `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - - function changeIdFieldsValuesInCsvFile(filePatch: string) { - // eslint-disable-next-line security/detect-non-literal-fs-filename - const fileContent = fs.readFileSync(filePatch).toString(); - const rows = fileContent.split('\n'); - const newRows = rows.map((row, index) => { - if (index === 0) { - return row; - } - const columns = row.split(','); - if (columns.length === 1) { - return row; - } - columns[0] = `5${index}`; - return columns.join(','); - }); - return newRows.join('\n'); - } - - const newFileContent = changeIdFieldsValuesInCsvFile(downloadedFilePatch); - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, newFileContent); - - const importCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) - .attach('file', downloadedFilePatch) - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - - const _importCsvResponseRO = JSON.parse(importCsvResponse.text); - t.is(importCsvResponse.status, 201); - - //checking that the lines was added - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(getTableRowsResponse.status, 200); - const addedRows = getTableRowsRO.rows.filter((row: Record) => row.id > testEntitiesSeedsCount); - t.is(addedRows.length, 2); + const connectionToTestDB = getTestData(mockFactory).connectionToMySQL; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post( + `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + + function changeIdFieldsValuesInCsvFile(filePatch: string) { + // eslint-disable-next-line security/detect-non-literal-fs-filename + const fileContent = fs.readFileSync(filePatch).toString(); + const rows = fileContent.split('\n'); + const newRows = rows.map((row, index) => { + if (index === 0) { + return row; + } + const columns = row.split(','); + if (columns.length === 1) { + return row; + } + columns[0] = `5${index}`; + return columns.join(','); + }); + return newRows.join('\n'); + } + + const newFileContent = changeIdFieldsValuesInCsvFile(downloadedFilePatch); + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, newFileContent); + + const importCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) + .attach('file', downloadedFilePatch) + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + + const _importCsvResponseRO = JSON.parse(importCsvResponse.text); + t.is(importCsvResponse.status, 201); + + //checking that the lines was added + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(getTableRowsResponse.status, 200); + const addedRows = getTableRowsRO.rows.filter((row: Record) => row.id > testEntitiesSeedsCount); + t.is(addedRows.length, 2); }); diff --git a/backend/test/ava-tests/saas-tests/table-oracledb-e2e.test.ts b/backend/test/ava-tests/saas-tests/table-oracledb-e2e.test.ts index 201acbde7..a28c97452 100644 --- a/backend/test/ava-tests/saas-tests/table-oracledb-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/table-oracledb-e2e.test.ts @@ -39,4168 +39,4168 @@ const testTables: Array = []; let currentTest; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - await dropTestTables(testTables, connectionToTestDB); - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + await dropTestTables(testTables, connectionToTestDB); + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /connection/tables/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTablesRO = JSON.parse(getTablesResponse.text); - t.is(getTablesResponse.status, 200); - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.length > 0, true); - - const testTableIndex = getTablesRO.findIndex((t) => { - return t.table === testTableName; - }); - - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); - t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); - t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); - t.is(getTablesRO[testTableIndex].table, testTableName); - t.is(getTablesRO[testTableIndex].permissions.visibility, true); - t.is(getTablesRO[testTableIndex].permissions.readonly, false); - t.is(getTablesRO[testTableIndex].permissions.add, true); - t.is(getTablesRO[testTableIndex].permissions.delete, true); - t.is(getTablesRO[testTableIndex].permissions.edit, true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTablesRO = JSON.parse(getTablesResponse.text); + t.is(getTablesResponse.status, 200); + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.length > 0, true); + + const testTableIndex = getTablesRO.findIndex((t) => { + return t.table === testTableName; + }); + + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); + t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); + t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); + t.is(getTablesRO[testTableIndex].table, testTableName); + t.is(getTablesRO[testTableIndex].permissions.visibility, true); + t.is(getTablesRO[testTableIndex].permissions.readonly, false); + t.is(getTablesRO[testTableIndex].permissions.add, true); + t.is(getTablesRO[testTableIndex].permissions.delete, true); + t.is(getTablesRO[testTableIndex].permissions.edit, true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connectionId not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = ''; - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = ''; + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connection id is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = faker.string.uuid(); - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 400); - const { message } = JSON.parse(getTablesResponse.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = faker.string.uuid(); + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 400); + const { message } = JSON.parse(getTablesResponse.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return rows of selected table without search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return rows of selected table with search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createPersonalTableSettingsRO = JSON.parse(createPersonalTableSettingsResponse.text); - console.log('🚀 ~ createPersonalTableSettingsRO:', createPersonalTableSettingsRO); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const _createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); - t.is(createTableSettingsResponse.status, 201); - - const searchedDescription = '25'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(getTableRowsResponse.status, 200); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createPersonalTableSettingsRO = JSON.parse(createPersonalTableSettingsResponse.text); + console.log('🚀 ~ createPersonalTableSettingsRO:', createPersonalTableSettingsRO); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); + t.is(createTableSettingsResponse.status, 201); + + const searchedDescription = '25'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(getTableRowsResponse.status, 200); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=1, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Content-Type', 'application/json') - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=3, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 3); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 3); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - // t.is(getTableRowsRO.pagination.total, 42); - // t.is(getTableRowsRO.pagination.lastPage, 2); - // t.is(getTableRowsRO.pagination.perPage, 2); - // t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + // t.is(getTableRowsRO.pagination.total, 42); + // t.is(getTableRowsRO.pagination.lastPage, 2); + // t.is(getTableRowsRO.pagination.perPage, 2); + // t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - // t.is(getTableRowsRO.pagination.total, 42); - // t.is(getTableRowsRO.pagination.lastPage, 2); - // t.is(getTableRowsRO.pagination.perPage, 2); - // t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + // t.is(getTableRowsRO.pagination.total, 42); + // t.is(getTableRowsRO.pagination.lastPage, 2); + // t.is(getTableRowsRO.pagination.perPage, 2); + // t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by DESC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - t.is(getTableRowsRO.rows[41].id, 1); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + t.is(getTableRowsRO.rows[41].id, 1); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by ASC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - t.is(getTableRowsRO.rows[41].id, 42); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + t.is(getTableRowsRO.rows[41].id, 42); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and with pagination and with sorting + `${currentTest} without search and with pagination and with sorting should return all found rows with sorting ports by DESC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 39); - t.is(getTableRowsRO.rows[1].id, 38); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 39); + t.is(getTableRowsRO.rows[1].id, 38); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '45'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '45'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with pagination, with sorting and with filtering by date fields + `${currentTest} with pagination, with sorting and with filtering by date fields should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const _createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const firstFieldName = 'created_at'; - const _secondFieldName = 'updated_at'; - const firstFieldValue = '2011-11-03'; - - const filters = { - [firstFieldName]: { lt: firstFieldValue }, - }; - - const getTableRowsResponse = await request(app.getHttpServer()) - .post(`/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .send({ filters }) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(getTableRowsResponse.status, 201); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const _createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const firstFieldName = 'created_at'; + const _secondFieldName = 'updated_at'; + const firstFieldValue = '2011-11-03'; + + const filters = { + [firstFieldName]: { lt: firstFieldValue }, + }; + + const getTableRowsResponse = await request(app.getHttpServer()) + .post(`/table/rows/find/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .send({ filters }) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(getTableRowsResponse.status, 201); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=10 and DESC sorting and filtering'`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[2].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 10); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[2].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 10); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and with multi filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - createConnectionRO.id = ''; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + createConnectionRO.id = ''; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - createConnectionRO.id = faker.string.uuid(); - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 403); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + createConnectionRO.id = faker.string.uuid(); + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 403); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 400); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 400); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = faker.lorem.words(1); - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTablesRO = JSON.parse(getTableRowsResponse.text); - t.is(getTablesRO.rows.length, 2); - t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTablesRO, 'pagination'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = faker.lorem.words(1); + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTablesRO = JSON.parse(getTableRowsResponse.text); + t.is(getTablesRO.rows.length, 2); + t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTablesRO, 'pagination'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 200); - const getTableStructureRO = JSON.parse(getTableStructure.text); - - t.is(typeof getTableStructureRO, 'object'); - t.is(typeof getTableStructureRO.structure, 'object'); - t.is(getTableStructureRO.structure.length, 5); - - for (const element of getTableStructureRO.structure) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'column_default'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - t.is(Object.hasOwn(element, 'isExcluded'), true); - t.is(Object.hasOwn(element, 'isSearched'), true); - } - - t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); - - for (const element of getTableStructureRO.primaryColumns) { - t.is(Object.hasOwn(element, 'column_name'), true); - // t.is(element.hasOwnProperty('data_type'), true); - } - - for (const element of getTableStructureRO.foreignKeys) { - t.is(Object.hasOwn(element, 'referenced_column_name'), true); - t.is(Object.hasOwn(element, 'referenced_table_name'), true); - t.is(Object.hasOwn(element, 'constraint_name'), true); - t.is(Object.hasOwn(element, 'column_name'), true); - } + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 200); + const getTableStructureRO = JSON.parse(getTableStructure.text); + + t.is(typeof getTableStructureRO, 'object'); + t.is(typeof getTableStructureRO.structure, 'object'); + t.is(getTableStructureRO.structure.length, 5); + + for (const element of getTableStructureRO.structure) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'column_default'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + t.is(Object.hasOwn(element, 'isExcluded'), true); + t.is(Object.hasOwn(element, 'isSearched'), true); + } + + t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); + + for (const element of getTableStructureRO.primaryColumns) { + t.is(Object.hasOwn(element, 'column_name'), true); + // t.is(element.hasOwnProperty('data_type'), true); + } + + for (const element of getTableStructureRO.foreignKeys) { + t.is(Object.hasOwn(element, 'referenced_column_name'), true); + t.is(Object.hasOwn(element, 'referenced_table_name'), true); + t.is(Object.hasOwn(element, 'constraint_name'), true); + t.is(Object.hasOwn(element, 'column_name'), true); + } }); test.serial(`${currentTest} should throw an exception whe connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 404); }); test.serial(`${currentTest} should throw an exception whe connection id passed in request id incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = faker.string.uuid(); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 403); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = faker.string.uuid(); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 403); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest}should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = faker.lorem.words(1); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = faker.lorem.words(1); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should add row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 43, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addRowInTableRO = JSON.parse(addRowInTableResponse.text); - t.is(addRowInTableResponse.status, 201); - - t.is(Object.hasOwn(addRowInTableRO, 'row'), true); - t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); - t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 43); - t.is(rows[42][testTableColumnName], row[testTableColumnName]); - t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); - t.is(rows[42].id, rows[41].id + 1); - - // check that rows adding was logged - - const getLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getLogsResponse.status, 200); - const getLogsRO = JSON.parse(getLogsResponse.text); - t.is(Object.hasOwn(getLogsRO, 'logs'), true); - t.is(Object.hasOwn(getLogsRO, 'pagination'), true); - t.is(getLogsRO.logs.length > 0, true); - const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); - t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); - // t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, 43); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 43, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addRowInTableRO = JSON.parse(addRowInTableResponse.text); + t.is(addRowInTableResponse.status, 201); + + t.is(Object.hasOwn(addRowInTableRO, 'row'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 43); + t.is(rows[42][testTableColumnName], row[testTableColumnName]); + t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); + t.is(rows[42].id, rows[41].id + 1); + + // check that rows adding was logged + + const getLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getLogsResponse.status, 200); + const getLogsRO = JSON.parse(getLogsResponse.text); + t.is(Object.hasOwn(getLogsRO, 'logs'), true); + t.is(Object.hasOwn(getLogsRO, 'pagination'), true); + t.is(getLogsRO.logs.length > 0, true); + const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); + t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); + // t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, 43); }); test.serial(`${currentTest} should add row in table with date column and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 44, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - updated_at: null, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addRowInTableRO = JSON.parse(addRowInTableResponse.text); - t.is(addRowInTableResponse.status, 201); - - t.is(Object.hasOwn(addRowInTableRO, 'row'), true); - t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); - t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 43); - t.is(rows[42][testTableColumnName], row[testTableColumnName]); - t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); - t.is(rows[42].id, rows[41].id + 2); - - // check that rows adding was logged - - const getLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getLogsResponse.status, 200); - const getLogsRO = JSON.parse(getLogsResponse.text); - t.is(Object.hasOwn(getLogsRO, 'logs'), true); - t.is(Object.hasOwn(getLogsRO, 'pagination'), true); - t.is(getLogsRO.logs.length > 0, true); - const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); - t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); - // t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, 44); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 44, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + updated_at: null, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addRowInTableRO = JSON.parse(addRowInTableResponse.text); + t.is(addRowInTableResponse.status, 201); + + t.is(Object.hasOwn(addRowInTableRO, 'row'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 43); + t.is(rows[42][testTableColumnName], row[testTableColumnName]); + t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); + t.is(rows[42].id, rows[41].id + 2); + + // check that rows adding was logged + + const getLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getLogsResponse.status, 200); + const getLogsRO = JSON.parse(getLogsResponse.text); + t.is(Object.hasOwn(getLogsRO, 'logs'), true); + t.is(Object.hasOwn(getLogsRO, 'pagination'), true); + t.is(getLogsRO.logs.length > 0, true); + const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); + t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); + // t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, 44); }); test.serial(`${currentTest} should add row in table with with different data`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTableWithDifferentData(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const _fakeName = faker.person.firstName(); - const _fakeMail = faker.internet.email(); - - const row = { - first_name: 'sdfdf', - last_name: 'sdfdfsf', - date_of_birth: '2025-09-02', - gender: 'F', - phone_number: '324536456456', - email: 'dfgd@dgdfg.fg', - address: 'tsdgd', - insurance_info: 'dfgdfgdfg', - created_at: null, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addRowInTableRO = JSON.parse(addRowInTableResponse.text); - console.log('🚀 ~ addRowInTableRO:', addRowInTableRO); - t.is(addRowInTableResponse.status, 201); - - t.is(Object.hasOwn(addRowInTableRO, 'row'), true); - t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTableWithDifferentData(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const _fakeName = faker.person.firstName(); + const _fakeMail = faker.internet.email(); + + const row = { + first_name: 'sdfdf', + last_name: 'sdfdfsf', + date_of_birth: '2025-09-02', + gender: 'F', + phone_number: '324536456456', + email: 'dfgd@dgdfg.fg', + address: 'tsdgd', + insurance_info: 'dfgdfgdfg', + created_at: null, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addRowInTableRO = JSON.parse(addRowInTableResponse.text); + console.log('🚀 ~ addRowInTableRO:', addRowInTableRO); + t.is(addRowInTableResponse.status, 201); + + t.is(Object.hasOwn(addRowInTableRO, 'row'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); }); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const fakeConnectionId = ''; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 404); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const fakeConnectionId = ''; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 404); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when row is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.PARAMETER_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.PARAMETER_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); currentTest = 'PUT /table/row/:slug'; test.serial(`${currentTest} should update row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 200); - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); - t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was updated - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - const updateRowIndex = rows.map((row) => row.id).indexOf(1); - t.is(rows.length, 42); - t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); - t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 200); + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); + t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was updated + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + const updateRowIndex = rows.map((row) => row.id).indexOf(1); + t.is(rows.length, 42); + t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); + t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = ''; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = ''; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 404); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 403); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 403); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/update/:connectionId'; test.serial(`${currentTest} should update multiple rows and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const requestData = { - primaryKeys: [{ id: 1 }, { id: 2 }], - newValues: { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(requestData)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(updateRowInTableResponse.status, 200); - t.is(updateRowInTableRO.success, true); - - // check that the rows were updated - const firstRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const firstRow = JSON.parse(firstRowResponse.text); - t.is(firstRowResponse.status, 200); - t.is(firstRow.row[testTableColumnName], fakeName); - t.is(firstRow.row[testTableSecondColumnName], fakeMail); - - const secondRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const secondRow = JSON.parse(secondRowResponse.text); - t.is(secondRowResponse.status, 200); - t.is(secondRow.row[testTableColumnName], fakeName); - t.is(secondRow.row[testTableSecondColumnName], fakeMail); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const requestData = { + primaryKeys: [{ id: 1 }, { id: 2 }], + newValues: { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(requestData)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(updateRowInTableResponse.status, 200); + t.is(updateRowInTableRO.success, true); + + // check that the rows were updated + const firstRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const firstRow = JSON.parse(firstRowResponse.text); + t.is(firstRowResponse.status, 200); + t.is(firstRow.row[testTableColumnName], fakeName); + t.is(firstRow.row[testTableSecondColumnName], fakeMail); + + const secondRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const secondRow = JSON.parse(secondRowResponse.text); + t.is(secondRowResponse.status, 200); + t.is(secondRow.row[testTableColumnName], fakeName); + t.is(secondRow.row[testTableSecondColumnName], fakeMail); }); currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 41); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, true); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 41); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, true); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 404); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 404); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = faker.string.uuid(); - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 403); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = faker.string.uuid(); + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 403); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - t.is(deleteRowInTableResponse.status, 400); - t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + t.is(deleteRowInTableResponse.status, 400); + t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} found row`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); - t.is(foundRowInTableResponse.status, 200); - - t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); - t.is(typeof foundRowInTableRO.row, 'object'); - t.is(typeof foundRowInTableRO.structure, 'object'); - t.is(typeof foundRowInTableRO.primaryColumns, 'object'); - t.is(typeof foundRowInTableRO.readonly_fields, 'object'); - t.is(typeof foundRowInTableRO.foreignKeys, 'object'); - t.is(foundRowInTableRO.row.id, 1); - t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); - t.is(Object.keys(foundRowInTableRO.row).length, 5); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); + t.is(foundRowInTableResponse.status, 200); + + t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); + t.is(typeof foundRowInTableRO.row, 'object'); + t.is(typeof foundRowInTableRO.structure, 'object'); + t.is(typeof foundRowInTableRO.primaryColumns, 'object'); + t.is(typeof foundRowInTableRO.readonly_fields, 'object'); + t.is(typeof foundRowInTableRO.foreignKeys, 'object'); + t.is(foundRowInTableRO.row.id, 1); + t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); + t.is(Object.keys(foundRowInTableRO.row).length, 5); }); test.serial(`${currentTest} should throw an exception, when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const idForSearch = 1; - createConnectionRO.id = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const idForSearch = 1; + createConnectionRO.id = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 404); }); test.serial( - `${currentTest} should throw an exception, when connection id passed in request is incorrect`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - createConnectionRO.id = faker.string.uuid(); - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 403); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - }, + `${currentTest} should throw an exception, when connection id passed in request is incorrect`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + createConnectionRO.id = faker.string.uuid(); + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 403); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + }, ); test.serial(`${currentTest} should throw an exception, when tableName in not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception, when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception, when primary key is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1000000; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1000000; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/delete/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const primaryKeysForDeletion: Array> = [ - { - id: 1, - }, - { - id: 10, - }, - { - id: 32, - }, - ]; - const deleteRowsInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) - .send(primaryKeysForDeletion) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowsInTableResponse.status, 200); - const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - // check that lines was deleted - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); - - for (const key of primaryKeysForDeletion) { - t.is( - rows.findIndex((row) => row.id === key.id), - -1, - ); - } - - // check that table deletaion was logged - const tableLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(tableLogsResponse.status, 200); - - const tableLogsRO = JSON.parse(tableLogsResponse.text); - t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); - const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); - for (const key of primaryKeysForDeletion) { - t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); - } + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const primaryKeysForDeletion: Array> = [ + { + id: 1, + }, + { + id: 10, + }, + { + id: 32, + }, + ]; + const deleteRowsInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) + .send(primaryKeysForDeletion) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowsInTableResponse.status, 200); + const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + // check that lines was deleted + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); + + for (const key of primaryKeysForDeletion) { + t.is( + rows.findIndex((row) => row.id === key.id), + -1, + ); + } + + // check that table deletaion was logged + const tableLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(tableLogsResponse.status, 200); + + const tableLogsRO = JSON.parse(tableLogsResponse.text); + t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); + const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); + for (const key of primaryKeysForDeletion) { + t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); + } }); currentTest = 'POST /connection/test/'; test.serial(`${currentTest} should test connection and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const testConnectionResponse = await request(app.getHttpServer()) - .post('/connection/test/') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse.status, 201); - const { message } = JSON.parse(testConnectionResponse.text); - t.is(message, 'Successfully connected'); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const testConnectionResponse = await request(app.getHttpServer()) + .post('/connection/test/') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse.status, 201); + const { message } = JSON.parse(testConnectionResponse.text); + t.is(message, 'Successfully connected'); }); currentTest = 'GET table/csv/:slug'; test.serial(`${currentTest} should return csv file with table data`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); }); test.serial( - `${currentTest} should return csv file with table data with search, with pagination, with sorting, + `${currentTest} should return csv file with table data with search, with pagination, with sorting, with search and pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post( - `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - }, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post( + `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + }, ); currentTest = 'POST /table/csv/import/:slug'; test.serial(`${currentTest} should import csv file with table data`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableCsvResponse = await request(app.getHttpServer()) - .post( - `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'text/csv') - .set('Accept', 'text/csv'); - - if (getTableCsvResponse.status !== 201) { - console.log(getTableCsvResponse.text); - } - t.is(getTableCsvResponse.status, 201); - const fileName = `${testTableName}.csv`; - const downloadedFilePatch = join(os.tmpdir(), fileName); - - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); - // eslint-disable-next-line security/detect-non-literal-fs-filename - const isFileExists = fs.existsSync(downloadedFilePatch); - t.is(isFileExists, true); - - function changeIdFieldsValuesInCsvFile(filePatch: string) { - // eslint-disable-next-line security/detect-non-literal-fs-filename - const fileContent = fs.readFileSync(filePatch).toString(); - const rows = fileContent.split('\n'); - const newRows = rows.map((row, index) => { - if (index === 0) { - return row; - } - const columns = row.split(','); - if (columns.length === 1) { - return row; - } - columns[0] = `5${index}`; - return columns.join(','); - }); - return newRows.join('\n'); - } - - const newFileContent = changeIdFieldsValuesInCsvFile(downloadedFilePatch); - // eslint-disable-next-line security/detect-non-literal-fs-filename - fs.writeFileSync(downloadedFilePatch, newFileContent); - - const importCsvResponse = await request(app.getHttpServer()) - .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) - .attach('file', downloadedFilePatch) - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - - t.is(importCsvResponse.status, 201); - - //checking that the lines was added - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(getTableRowsResponse.status, 200); - const addedRows = getTableRowsRO.rows.filter((row: Record) => row.id > testEntitiesSeedsCount); - t.is(addedRows.length, 3); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableCsvResponse = await request(app.getHttpServer()) + .post( + `/table/csv/export/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'text/csv') + .set('Accept', 'text/csv'); + + if (getTableCsvResponse.status !== 201) { + console.log(getTableCsvResponse.text); + } + t.is(getTableCsvResponse.status, 201); + const fileName = `${testTableName}.csv`; + const downloadedFilePatch = join(os.tmpdir(), fileName); + + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, getTableCsvResponse.body); + // eslint-disable-next-line security/detect-non-literal-fs-filename + const isFileExists = fs.existsSync(downloadedFilePatch); + t.is(isFileExists, true); + + function changeIdFieldsValuesInCsvFile(filePatch: string) { + // eslint-disable-next-line security/detect-non-literal-fs-filename + const fileContent = fs.readFileSync(filePatch).toString(); + const rows = fileContent.split('\n'); + const newRows = rows.map((row, index) => { + if (index === 0) { + return row; + } + const columns = row.split(','); + if (columns.length === 1) { + return row; + } + columns[0] = `5${index}`; + return columns.join(','); + }); + return newRows.join('\n'); + } + + const newFileContent = changeIdFieldsValuesInCsvFile(downloadedFilePatch); + // eslint-disable-next-line security/detect-non-literal-fs-filename + fs.writeFileSync(downloadedFilePatch, newFileContent); + + const importCsvResponse = await request(app.getHttpServer()) + .post(`/table/csv/import/${createConnectionRO.id}?tableName=${testTableName}`) + .attach('file', downloadedFilePatch) + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + + t.is(importCsvResponse.status, 201); + + //checking that the lines was added + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(getTableRowsResponse.status, 200); + const addedRows = getTableRowsRO.rows.filter((row: Record) => row.id > testEntitiesSeedsCount); + t.is(addedRows.length, 3); }); diff --git a/backend/test/ava-tests/saas-tests/table-oracledb-schema-e2e.test.ts b/backend/test/ava-tests/saas-tests/table-oracledb-schema-e2e.test.ts index bccdcd870..8511ca5e5 100644 --- a/backend/test/ava-tests/saas-tests/table-oracledb-schema-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/table-oracledb-schema-e2e.test.ts @@ -32,3697 +32,3697 @@ const testTables: Array = []; let currentTest; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication() as any; - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication() as any; + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - await dropTestTables(testTables, connectionToTestDB); - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + await dropTestTables(testTables, connectionToTestDB); + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /connection/tables/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 200); - const getTablesRO = JSON.parse(getTablesResponse.text); - - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.length > 0, true); - - const testTableIndex = getTablesRO.findIndex((t) => { - return t.table === testTableName; - }); - - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); - t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); - t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); - t.is(getTablesRO[testTableIndex].table, testTableName); - t.is(getTablesRO[testTableIndex].permissions.visibility, true); - t.is(getTablesRO[testTableIndex].permissions.readonly, false); - t.is(getTablesRO[testTableIndex].permissions.add, true); - t.is(getTablesRO[testTableIndex].permissions.delete, true); - t.is(getTablesRO[testTableIndex].permissions.edit, true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 200); + const getTablesRO = JSON.parse(getTablesResponse.text); + + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.length > 0, true); + + const testTableIndex = getTablesRO.findIndex((t) => { + return t.table === testTableName; + }); + + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); + t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); + t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); + t.is(getTablesRO[testTableIndex].table, testTableName); + t.is(getTablesRO[testTableIndex].permissions.visibility, true); + t.is(getTablesRO[testTableIndex].permissions.readonly, false); + t.is(getTablesRO[testTableIndex].permissions.add, true); + t.is(getTablesRO[testTableIndex].permissions.delete, true); + t.is(getTablesRO[testTableIndex].permissions.edit, true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connectionId not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = ''; - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = ''; + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connection id is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = faker.string.uuid(); - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 400); - const { message } = JSON.parse(getTablesResponse.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = faker.string.uuid(); + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 400); + const { message } = JSON.parse(getTablesResponse.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return rows of selected table without search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return rows of selected table with search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createTableSettingsResponse.status, 201); - - const searchedDescription = '25'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const searchedDescription = '25'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=1, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Content-Type', 'application/json') - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=3, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 3); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 3); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - // t.is(getTableRowsRO.pagination.total, 42); - // t.is(getTableRowsRO.pagination.lastPage, 2); - // t.is(getTableRowsRO.pagination.perPage, 2); - // t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + // t.is(getTableRowsRO.pagination.total, 42); + // t.is(getTableRowsRO.pagination.lastPage, 2); + // t.is(getTableRowsRO.pagination.perPage, 2); + // t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); - - // t.is(getTableRowsRO.pagination.total, 42); - // t.is(getTableRowsRO.pagination.lastPage, 2); - // t.is(getTableRowsRO.pagination.perPage, 2); - // t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + // t.is(getTableRowsRO.primaryColumns[0].data_type, 'int'); + + // t.is(getTableRowsRO.pagination.total, 42); + // t.is(getTableRowsRO.pagination.lastPage, 2); + // t.is(getTableRowsRO.pagination.perPage, 2); + // t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by DESC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - t.is(getTableRowsRO.rows[41].id, 1); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + t.is(getTableRowsRO.rows[41].id, 1); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by ASC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - t.is(getTableRowsRO.rows[41].id, 42); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + t.is(getTableRowsRO.rows[41].id, 42); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and with pagination and with sorting + `${currentTest} without search and with pagination and with sorting should return all found rows with sorting ports by DESC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 39); - t.is(getTableRowsRO.rows[1].id, 38); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 39); + t.is(getTableRowsRO.rows[1].id, 38); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '45'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '45'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=10 and DESC sorting and filtering'`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[2].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 10); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[2].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 10); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and with multi filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + // t.is(getTableRowsRO.primaryColumns[0].hasOwnProperty('data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - createConnectionRO.id = ''; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + createConnectionRO.id = ''; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - createConnectionRO.id = faker.string.uuid(); - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 403); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + createConnectionRO.id = faker.string.uuid(); + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 403); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 400); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 400); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = faker.lorem.words(1); - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTablesRO = JSON.parse(getTableRowsResponse.text); - t.is(getTablesRO.rows.length, 2); - t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTablesRO, 'pagination'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = faker.lorem.words(1); + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTablesRO = JSON.parse(getTableRowsResponse.text); + t.is(getTablesRO.rows.length, 2); + t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTablesRO, 'pagination'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 200); - const getTableStructureRO = JSON.parse(getTableStructure.text); - - t.is(typeof getTableStructureRO, 'object'); - t.is(typeof getTableStructureRO.structure, 'object'); - t.is(getTableStructureRO.structure.length, 5); - - for (const element of getTableStructureRO.structure) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'column_default'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - t.is(Object.hasOwn(element, 'isExcluded'), true); - t.is(Object.hasOwn(element, 'isSearched'), true); - } - - t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); - - for (const element of getTableStructureRO.primaryColumns) { - t.is(Object.hasOwn(element, 'column_name'), true); - // t.is(element.hasOwnProperty('data_type'), true); - } - - for (const element of getTableStructureRO.foreignKeys) { - t.is(Object.hasOwn(element, 'referenced_column_name'), true); - t.is(Object.hasOwn(element, 'referenced_table_name'), true); - t.is(Object.hasOwn(element, 'constraint_name'), true); - t.is(Object.hasOwn(element, 'column_name'), true); - } + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 200); + const getTableStructureRO = JSON.parse(getTableStructure.text); + + t.is(typeof getTableStructureRO, 'object'); + t.is(typeof getTableStructureRO.structure, 'object'); + t.is(getTableStructureRO.structure.length, 5); + + for (const element of getTableStructureRO.structure) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'column_default'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + t.is(Object.hasOwn(element, 'isExcluded'), true); + t.is(Object.hasOwn(element, 'isSearched'), true); + } + + t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); + + for (const element of getTableStructureRO.primaryColumns) { + t.is(Object.hasOwn(element, 'column_name'), true); + // t.is(element.hasOwnProperty('data_type'), true); + } + + for (const element of getTableStructureRO.foreignKeys) { + t.is(Object.hasOwn(element, 'referenced_column_name'), true); + t.is(Object.hasOwn(element, 'referenced_table_name'), true); + t.is(Object.hasOwn(element, 'constraint_name'), true); + t.is(Object.hasOwn(element, 'column_name'), true); + } }); test.serial(`${currentTest} should throw an exception whe connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 404); }); test.serial(`${currentTest} should throw an exception whe connection id passed in request id incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = faker.string.uuid(); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 403); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = faker.string.uuid(); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 403); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest}should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = faker.lorem.words(1); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = faker.lorem.words(1); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should add row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 43, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addRowInTableRO = JSON.parse(addRowInTableResponse.text); - t.is(addRowInTableResponse.status, 201); - - t.is(Object.hasOwn(addRowInTableRO, 'row'), true); - t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); - t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 43); - t.is(rows[42][testTableColumnName], row[testTableColumnName]); - t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); - t.is(rows[42].id, rows[41].id + 1); - - // check that rows adding was logged - - const getLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getLogsResponse.status, 200); - const getLogsRO = JSON.parse(getLogsResponse.text); - t.is(Object.hasOwn(getLogsRO, 'logs'), true); - t.is(Object.hasOwn(getLogsRO, 'pagination'), true); - t.is(getLogsRO.logs.length > 0, true); - const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); - t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); - t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, String(43)); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 43, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addRowInTableRO = JSON.parse(addRowInTableResponse.text); + t.is(addRowInTableResponse.status, 201); + + t.is(Object.hasOwn(addRowInTableRO, 'row'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 43); + t.is(rows[42][testTableColumnName], row[testTableColumnName]); + t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); + t.is(rows[42].id, rows[41].id + 1); + + // check that rows adding was logged + + const getLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getLogsResponse.status, 200); + const getLogsRO = JSON.parse(getLogsResponse.text); + t.is(Object.hasOwn(getLogsRO, 'logs'), true); + t.is(Object.hasOwn(getLogsRO, 'pagination'), true); + t.is(getLogsRO.logs.length > 0, true); + const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); + t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); + t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, String(43)); }); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const fakeConnectionId = ''; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 404); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const fakeConnectionId = ''; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 404); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when row is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.PARAMETER_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.PARAMETER_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); currentTest = 'PUT /table/row/:slug'; test.serial(`${currentTest} should update row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 200); - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); - t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was updated - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - const updateRowIndex = rows.map((row) => row.id).indexOf(1); - t.is(rows.length, 42); - t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); - t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 200); + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); + t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was updated + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + const updateRowIndex = rows.map((row) => row.id).indexOf(1); + t.is(rows.length, 42); + t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); + t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = ''; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = ''; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 404); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 403); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 403); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/update/:connectionId'; test.serial(`${currentTest} should update multiple rows and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const requestData = { - primaryKeys: [{ id: 1 }, { id: 2 }], - newValues: { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(requestData)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(updateRowInTableResponse.status, 200); - t.is(updateRowInTableRO.success, true); - - // check that the rows were updated - const firstRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const firstRow = JSON.parse(firstRowResponse.text); - t.is(firstRowResponse.status, 200); - t.is(firstRow.row[testTableColumnName], fakeName); - t.is(firstRow.row[testTableSecondColumnName], fakeMail); - - const secondRowResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const secondRow = JSON.parse(secondRowResponse.text); - t.is(secondRowResponse.status, 200); - t.is(secondRow.row[testTableColumnName], fakeName); - t.is(secondRow.row[testTableSecondColumnName], fakeMail); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const requestData = { + primaryKeys: [{ id: 1 }, { id: 2 }], + newValues: { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/update/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(requestData)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(updateRowInTableResponse.status, 200); + t.is(updateRowInTableRO.success, true); + + // check that the rows were updated + const firstRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const firstRow = JSON.parse(firstRowResponse.text); + t.is(firstRowResponse.status, 200); + t.is(firstRow.row[testTableColumnName], fakeName); + t.is(firstRow.row[testTableSecondColumnName], fakeMail); + + const secondRowResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const secondRow = JSON.parse(secondRowResponse.text); + t.is(secondRowResponse.status, 200); + t.is(secondRow.row[testTableColumnName], fakeName); + t.is(secondRow.row[testTableSecondColumnName], fakeMail); }); currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 41); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, true); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 41); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, true); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 404); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 404); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = faker.string.uuid(); - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 403); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = faker.string.uuid(); + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 403); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - t.is(deleteRowInTableResponse.status, 400); - t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + t.is(deleteRowInTableResponse.status, 400); + t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} found row`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 200); - const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); - t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); - t.is(typeof foundRowInTableRO.row, 'object'); - t.is(typeof foundRowInTableRO.structure, 'object'); - t.is(typeof foundRowInTableRO.primaryColumns, 'object'); - t.is(typeof foundRowInTableRO.readonly_fields, 'object'); - t.is(typeof foundRowInTableRO.foreignKeys, 'object'); - t.is(foundRowInTableRO.row.id, 1); - t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); - t.is(Object.keys(foundRowInTableRO.row).length, 5); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 200); + const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); + t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); + t.is(typeof foundRowInTableRO.row, 'object'); + t.is(typeof foundRowInTableRO.structure, 'object'); + t.is(typeof foundRowInTableRO.primaryColumns, 'object'); + t.is(typeof foundRowInTableRO.readonly_fields, 'object'); + t.is(typeof foundRowInTableRO.foreignKeys, 'object'); + t.is(foundRowInTableRO.row.id, 1); + t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); + t.is(Object.keys(foundRowInTableRO.row).length, 5); }); test.serial(`${currentTest} should throw an exception, when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const idForSearch = 1; - createConnectionRO.id = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const idForSearch = 1; + createConnectionRO.id = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 404); }); test.serial( - `${currentTest} should throw an exception, when connection id passed in request is incorrect`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - createConnectionRO.id = faker.string.uuid(); - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 403); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - }, + `${currentTest} should throw an exception, when connection id passed in request is incorrect`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + createConnectionRO.id = faker.string.uuid(); + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 403); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + }, ); test.serial(`${currentTest} should throw an exception, when tableName in not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception, when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception, when primary key is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1000000; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1000000; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/delete/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestOracleTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const primaryKeysForDeletion: Array> = [ - { - id: 1, - }, - { - id: 10, - }, - { - id: 32, - }, - ]; - const deleteRowsInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) - .send(primaryKeysForDeletion) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowsInTableResponse.status, 200); - const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - // check that lines was deleted - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); - - for (const key of primaryKeysForDeletion) { - t.is( - rows.findIndex((row) => row.id === key.id), - -1, - ); - } - - // check that table deletaion was logged - const tableLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(tableLogsResponse.status, 200); - - const tableLogsRO = JSON.parse(tableLogsResponse.text); - t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); - const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); - for (const key of primaryKeysForDeletion) { - t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); - } + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDBSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestOracleTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const primaryKeysForDeletion: Array> = [ + { + id: 1, + }, + { + id: 10, + }, + { + id: 32, + }, + ]; + const deleteRowsInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) + .send(primaryKeysForDeletion) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowsInTableResponse.status, 200); + const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + // check that lines was deleted + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); + + for (const key of primaryKeysForDeletion) { + t.is( + rows.findIndex((row) => row.id === key.id), + -1, + ); + } + + // check that table deletaion was logged + const tableLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(tableLogsResponse.status, 200); + + const tableLogsRO = JSON.parse(tableLogsResponse.text); + t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); + const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); + for (const key of primaryKeysForDeletion) { + t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); + } }); test.serial(`${currentTest} should test connection and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const testConnectionResponse = await request(app.getHttpServer()) - .post('/connection/test/') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse.status, 201); - const { message } = JSON.parse(testConnectionResponse.text); - t.is(message, 'Successfully connected'); + const connectionToTestDB = getTestData(mockFactory).connectionToOracleDB; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const testConnectionResponse = await request(app.getHttpServer()) + .post('/connection/test/') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse.status, 201); + const { message } = JSON.parse(testConnectionResponse.text); + t.is(message, 'Successfully connected'); }); diff --git a/backend/test/ava-tests/saas-tests/table-postgres-encrypted-e2e.test.ts b/backend/test/ava-tests/saas-tests/table-postgres-encrypted-e2e.test.ts index 923f94d96..a227b25a9 100644 --- a/backend/test/ava-tests/saas-tests/table-postgres-encrypted-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/table-postgres-encrypted-e2e.test.ts @@ -33,3747 +33,3747 @@ let currentTest; const masterPwd = faker.internet.password(); test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - await dropTestTables(testTables, connectionToTestDB); - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + await dropTestTables(testTables, connectionToTestDB); + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /connection/tables/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 200); - const getTablesRO = JSON.parse(getTablesResponse.text); - - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.length > 0, true); - - const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); - - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); - t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); - t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); - t.is(getTablesRO[testTableIndex].table, testTableName); - t.is(getTablesRO[testTableIndex].permissions.visibility, true); - t.is(getTablesRO[testTableIndex].permissions.readonly, false); - t.is(getTablesRO[testTableIndex].permissions.add, true); - t.is(getTablesRO[testTableIndex].permissions.delete, true); - t.is(getTablesRO[testTableIndex].permissions.edit, true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 200); + const getTablesRO = JSON.parse(getTablesResponse.text); + + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.length > 0, true); + + const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); + + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); + t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); + t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); + t.is(getTablesRO[testTableIndex].table, testTableName); + t.is(getTablesRO[testTableIndex].permissions.visibility, true); + t.is(getTablesRO[testTableIndex].permissions.readonly, false); + t.is(getTablesRO[testTableIndex].permissions.add, true); + t.is(getTablesRO[testTableIndex].permissions.delete, true); + t.is(getTablesRO[testTableIndex].permissions.edit, true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when master password is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const incorrectMasterPwd = faker.internet.password(); - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('masterpwd', incorrectMasterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 400); - const getTablesRO = JSON.parse(getTablesResponse.text); - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.message, Messages.MASTER_PASSWORD_INCORRECT); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const incorrectMasterPwd = faker.internet.password(); + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('masterpwd', incorrectMasterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 400); + const getTablesRO = JSON.parse(getTablesResponse.text); + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.message, Messages.MASTER_PASSWORD_INCORRECT); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connectionId not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = ''; - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = ''; + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connection id is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = faker.string.uuid(); - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 400); - const { message } = JSON.parse(getTablesResponse.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = faker.string.uuid(); + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 400); + const { message } = JSON.parse(getTablesResponse.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return rows of selected table without search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return rows of selected table with search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createTableSettingsResponse.status, 201); - - const searchedDescription = '5'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const searchedDescription = '5'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=1, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=3, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 3); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 3); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by DESC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - t.is(getTableRowsRO.rows[41].id, 1); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + t.is(getTableRowsRO.rows[41].id, 1); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by ASC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - t.is(getTableRowsRO.rows[41].id, 42); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + t.is(getTableRowsRO.rows[41].id, 42); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and with pagination and with sorting + `${currentTest} without search and with pagination and with sorting should return all found rows with sorting ports by DESC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 39); - t.is(getTableRowsRO.rows[1].id, 38); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 39); + t.is(getTableRowsRO.rows[1].id, 38); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '45'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '45'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=10 and DESC sorting and filtering'`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[2].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 10); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[2].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 10); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and with multi filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - createConnectionRO.id = ''; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + createConnectionRO.id = ''; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - createConnectionRO.id = faker.string.uuid(); - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 403); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + createConnectionRO.id = faker.string.uuid(); + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 403); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 400); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 400); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .set('masterpwd', masterPwd) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = faker.lorem.words(1); - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTablesRO = JSON.parse(getTableRowsResponse.text); - t.is(getTablesRO.rows.length, 2); - t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTablesRO, 'pagination'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .set('masterpwd', masterPwd) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = faker.lorem.words(1); + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTablesRO = JSON.parse(getTableRowsResponse.text); + t.is(getTablesRO.rows.length, 2); + t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTablesRO, 'pagination'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 200); - const getTableStructureRO = JSON.parse(getTableStructure.text); - - t.is(typeof getTableStructureRO, 'object'); - t.is(typeof getTableStructureRO.structure, 'object'); - t.is(getTableStructureRO.structure.length, 5); - - for (const element of getTableStructureRO.structure) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'column_default'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - t.is(Object.hasOwn(element, 'isExcluded'), true); - t.is(Object.hasOwn(element, 'isSearched'), true); - } - - t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); - - for (const element of getTableStructureRO.primaryColumns) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - } - - for (const element of getTableStructureRO.foreignKeys) { - t.is(Object.hasOwn(element, 'referenced_column_name'), true); - t.is(Object.hasOwn(element, 'referenced_table_name'), true); - t.is(Object.hasOwn(element, 'constraint_name'), true); - t.is(Object.hasOwn(element, 'column_name'), true); - } + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 200); + const getTableStructureRO = JSON.parse(getTableStructure.text); + + t.is(typeof getTableStructureRO, 'object'); + t.is(typeof getTableStructureRO.structure, 'object'); + t.is(getTableStructureRO.structure.length, 5); + + for (const element of getTableStructureRO.structure) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'column_default'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + t.is(Object.hasOwn(element, 'isExcluded'), true); + t.is(Object.hasOwn(element, 'isSearched'), true); + } + + t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); + + for (const element of getTableStructureRO.primaryColumns) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + } + + for (const element of getTableStructureRO.foreignKeys) { + t.is(Object.hasOwn(element, 'referenced_column_name'), true); + t.is(Object.hasOwn(element, 'referenced_table_name'), true); + t.is(Object.hasOwn(element, 'constraint_name'), true); + t.is(Object.hasOwn(element, 'column_name'), true); + } }); test.serial(`${currentTest} should throw an exception whe connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 404); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 404); }); test.serial(`${currentTest} should throw an exception whe connection id passed in request id incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = faker.string.uuid(); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 403); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = faker.string.uuid(); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 403); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest}should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should add row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addRowInTableRO = JSON.parse(addRowInTableResponse.text); - t.is(addRowInTableResponse.status, 201); - - t.is(Object.hasOwn(addRowInTableRO, 'row'), true); - t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); - t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 43); - t.is(rows[42][testTableColumnName], row[testTableColumnName]); - t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); - t.is(rows[42].id, rows[41].id + 1); - - // check that rows adding was logged - - const getLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getLogsResponse.status, 200); - const getLogsRO = JSON.parse(getLogsResponse.text); - t.is(Object.hasOwn(getLogsRO, 'logs'), true); - t.is(Object.hasOwn(getLogsRO, 'pagination'), true); - t.is(getLogsRO.logs.length > 0, true); - const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); - t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); - t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, 43); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addRowInTableRO = JSON.parse(addRowInTableResponse.text); + t.is(addRowInTableResponse.status, 201); + + t.is(Object.hasOwn(addRowInTableRO, 'row'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 43); + t.is(rows[42][testTableColumnName], row[testTableColumnName]); + t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); + t.is(rows[42].id, rows[41].id + 1); + + // check that rows adding was logged + + const getLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getLogsResponse.status, 200); + const getLogsRO = JSON.parse(getLogsResponse.text); + t.is(Object.hasOwn(getLogsRO, 'logs'), true); + t.is(Object.hasOwn(getLogsRO, 'pagination'), true); + t.is(getLogsRO.logs.length > 0, true); + const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); + t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); + t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, 43); }); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const fakeConnectionId = ''; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 404); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const fakeConnectionId = ''; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 404); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when row is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.PARAMETER_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.PARAMETER_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); currentTest = 'PUT /table/row/:slug'; test.serial(`${currentTest} should update row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 200); - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); - t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was updated - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - const updateRowIndex = rows.map((row) => row.id).indexOf(1); - t.is(rows.length, 42); - t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); - t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 200); + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); + t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was updated + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + const updateRowIndex = rows.map((row) => row.id).indexOf(1); + t.is(rows.length, 42); + t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); + t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = ''; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = ''; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 404); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 403); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 403); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 41); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, true); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 41); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, true); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 404); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 404); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = faker.string.uuid(); - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 403); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = faker.string.uuid(); + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 403); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - t.is(deleteRowInTableResponse.status, 400); - t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + t.is(deleteRowInTableResponse.status, 400); + t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} found row`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 200); - const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); - t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); - t.is(typeof foundRowInTableRO.row, 'object'); - t.is(typeof foundRowInTableRO.structure, 'object'); - t.is(typeof foundRowInTableRO.primaryColumns, 'object'); - t.is(typeof foundRowInTableRO.readonly_fields, 'object'); - t.is(typeof foundRowInTableRO.foreignKeys, 'object'); - t.is(foundRowInTableRO.row.id, 1); - t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); - t.is(Object.keys(foundRowInTableRO.row).length, 5); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 200); + const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); + t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); + t.is(typeof foundRowInTableRO.row, 'object'); + t.is(typeof foundRowInTableRO.structure, 'object'); + t.is(typeof foundRowInTableRO.primaryColumns, 'object'); + t.is(typeof foundRowInTableRO.readonly_fields, 'object'); + t.is(typeof foundRowInTableRO.foreignKeys, 'object'); + t.is(foundRowInTableRO.row.id, 1); + t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); + t.is(Object.keys(foundRowInTableRO.row).length, 5); }); test.serial(`${currentTest} should throw an exception, when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const idForSearch = 1; - createConnectionRO.id = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const idForSearch = 1; + createConnectionRO.id = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 404); }); test.serial( - `${currentTest} should throw an exception, when connection id passed in request is incorrect`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - createConnectionRO.id = faker.string.uuid(); - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 403); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - }, + `${currentTest} should throw an exception, when connection id passed in request is incorrect`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + createConnectionRO.id = faker.string.uuid(); + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 403); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + }, ); test.serial(`${currentTest} should throw an exception, when tableName in not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception, when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception, when primary key is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(foundRowInTableResponse.status, 400); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(foundRowInTableResponse.status, 400); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestTable(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1000000; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('masterpwd', masterPwd) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).encryptedPostgresConnection; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestTable(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1000000; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('masterpwd', masterPwd) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); diff --git a/backend/test/ava-tests/saas-tests/table-postgres-schema-e2e.test.ts b/backend/test/ava-tests/saas-tests/table-postgres-schema-e2e.test.ts index a48a30550..be7d37d15 100644 --- a/backend/test/ava-tests/saas-tests/table-postgres-schema-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/table-postgres-schema-e2e.test.ts @@ -32,3629 +32,3629 @@ const testTables: Array = []; let currentTest; test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - await dropTestTables(testTables, connectionToTestDB); - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + await dropTestTables(testTables, connectionToTestDB); + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /connection/tables/:slug'; test.serial(`${currentTest} should return list of tables in connection`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 200); - const getTablesRO = JSON.parse(getTablesResponse.text); - - t.is(typeof getTablesRO, 'object'); - t.is(getTablesRO.length > 0, true); - - const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); - - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); - t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); - t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); - t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); - t.is(getTablesRO[testTableIndex].table, testTableName); - t.is(getTablesRO[testTableIndex].permissions.visibility, true); - t.is(getTablesRO[testTableIndex].permissions.readonly, false); - t.is(getTablesRO[testTableIndex].permissions.add, true); - t.is(getTablesRO[testTableIndex].permissions.delete, true); - t.is(getTablesRO[testTableIndex].permissions.edit, true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 200); + const getTablesRO = JSON.parse(getTablesResponse.text); + + t.is(typeof getTablesRO, 'object'); + t.is(getTablesRO.length > 0, true); + + const testTableIndex = getTablesRO.findIndex((t) => t.table === testTableName); + + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'table'), true); + t.is(Object.hasOwn(getTablesRO[testTableIndex], 'permissions'), true); + t.is(typeof getTablesRO[testTableIndex].permissions, 'object'); + t.is(Object.keys(getTablesRO[testTableIndex].permissions).length, 5); + t.is(getTablesRO[testTableIndex].table, testTableName); + t.is(getTablesRO[testTableIndex].permissions.visibility, true); + t.is(getTablesRO[testTableIndex].permissions.readonly, false); + t.is(getTablesRO[testTableIndex].permissions.add, true); + t.is(getTablesRO[testTableIndex].permissions.delete, true); + t.is(getTablesRO[testTableIndex].permissions.edit, true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connectionId not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = ''; - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = ''; + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an error when connection id is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = faker.string.uuid(); - const getTablesResponse = await request(app.getHttpServer()) - .get(`/connection/tables/${createConnectionRO.id}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTablesResponse.status, 400); - const { message } = JSON.parse(getTablesResponse.text); - t.is(message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = faker.string.uuid(); + const getTablesResponse = await request(app.getHttpServer()) + .get(`/connection/tables/${createConnectionRO.id}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesResponse.status, 400); + const { message } = JSON.parse(getTablesResponse.text); + t.is(message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return rows of selected table without search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, Constants.DEFAULT_PAGINATION.perPage); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[10], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[15], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[19], 'updated_at'), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return rows of selected table with search and without pagination`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createTableSettingsResponse.status, 201); - - const searchedDescription = '5'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const searchedDescription = '5'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${searchedDescription}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, parseInt(searchedDescription, 10)); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], testTableSecondColumnName), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'created_at'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'updated_at'), true); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=1, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Content-Type', 'application/json') - .set('Cookie', firstUserToken) - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should return page of all rows with pagination page=3, perPage=2`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - ['id'], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); - t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); - - t.is(getTableRowsRO.pagination.total, 42); - t.is(getTableRowsRO.pagination.lastPage, 21); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 3); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + ['id'], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=3&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(Object.hasOwn(getTableRowsRO.rows[0], 'id'), true); + t.is(Object.hasOwn(getTableRowsRO.rows[1], testTableColumnName), true); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); + + t.is(getTableRowsRO.pagination.total, 42); + t.is(getTableRowsRO.pagination.lastPage, 21); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 3); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, without sorting + `${currentTest} with search, with pagination, without sorting should return all found rows with pagination page=1 perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - undefined, - undefined, - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); - t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); - - t.is(getTableRowsRO.pagination.total, 3); - t.is(getTableRowsRO.pagination.lastPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - t.is(getTableRowsRO.pagination.currentPage, 1); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + undefined, + undefined, + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + t.is(getTableRowsRO.primaryColumns[0].column_name, 'id'); + t.is(getTableRowsRO.primaryColumns[0].data_type, 'integer'); + + t.is(getTableRowsRO.pagination.total, 3); + t.is(getTableRowsRO.pagination.lastPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + t.is(getTableRowsRO.pagination.currentPage, 1); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by DESC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - t.is(getTableRowsRO.rows[41].id, 1); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + t.is(getTableRowsRO.rows[41].id, 1); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and without pagination and with sorting + `${currentTest} without search and without pagination and with sorting should return all found rows with sorting ids by ASC`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 42, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 42); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - t.is(getTableRowsRO.rows[41].id, 42); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 42, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 42); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + t.is(getTableRowsRO.rows[41].id, 42); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} without search and with pagination and with sorting + `${currentTest} without search and with pagination and with sorting should return all found rows with sorting ports by DESC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 42); - t.is(getTableRowsRO.rows[1].id, 41); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 42); + t.is(getTableRowsRO.rows[1].id, 41); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by ASC and with pagination page=1, perPage=2`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 39); - t.is(getTableRowsRO.rows[1].id, 38); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return all found rows with sorting ports by DESC and with pagination page=2, perPage=3`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=3`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 39); + t.is(getTableRowsRO.rows[1].id, 38); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=1, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 1); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 1); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination and with sorting + `${currentTest} with search, with pagination and with sorting should return all found rows with search, pagination: page=2, perPage=2 and ASC sorting`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.ASC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.ASC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=2&perPage=2&search=${testSearchedUserName}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '45'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 2); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '45'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 2); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=10 and DESC sorting and filtering'`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 3); - t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[1].id, 22); - t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[2].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 10); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=10&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 3); + t.is(Object.keys(getTableRowsRO.rows[1]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[1].id, 22); + t.is(getTableRowsRO.rows[2][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[2].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 10); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=2, perPage=2 and DESC sorting and filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldvalue = '41'; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTableRowsRO.rows[0].id, 1); - - t.is(getTableRowsRO.pagination.currentPage, 2); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldvalue = '41'; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=2&perPage=2&f_${fieldname}__lt=${fieldvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTableRowsRO.rows[0].id, 1); + + t.is(getTableRowsRO.pagination.currentPage, 2); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial( - `${currentTest} with search, with pagination, with sorting and with filtering + `${currentTest} with search, with pagination, with sorting and with filtering should return all found rows with search, pagination: page=1, perPage=2 and DESC sorting and with multi filtering`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(typeof getTableRowsRO, 'object'); - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - t.is(getTableRowsRO.rows.length, 1); - t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); - - t.is(getTableRowsRO.rows[0].id, 38); - t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); - - t.is(getTableRowsRO.pagination.currentPage, 1); - t.is(getTableRowsRO.pagination.perPage, 2); - - t.is(typeof getTableRowsRO.primaryColumns, 'object'); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); - t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(typeof getTableRowsRO, 'object'); + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + t.is(getTableRowsRO.rows.length, 1); + t.is(Object.keys(getTableRowsRO.rows[0]).length, 5); + + t.is(getTableRowsRO.rows[0].id, 38); + t.is(getTableRowsRO.rows[0][testTableColumnName], testSearchedUserName); + + t.is(getTableRowsRO.pagination.currentPage, 1); + t.is(getTableRowsRO.pagination.perPage, 2); + + t.is(typeof getTableRowsRO.primaryColumns, 'object'); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'column_name'), true); + t.is(Object.hasOwn(getTableRowsRO.primaryColumns[0], 'data_type'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - createConnectionRO.id = ''; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + createConnectionRO.id = ''; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - createConnectionRO.id = faker.string.uuid(); - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 403); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + createConnectionRO.id = faker.string.uuid(); + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 403); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = 'id'; - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 400); - - const { message } = JSON.parse(getTableRowsResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = 'id'; + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${fakeTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 400); + + const { message } = JSON.parse(getTableRowsResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } }); test.serial( - `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, - async (t) => { - try { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - createConnectionRO.id, - testTableName, - [testTableColumnName], - undefined, - undefined, - undefined, - undefined, - undefined, - undefined, - ); - - const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( - undefined, - 3, - QueryOrderingEnum.DESC, - 'id', - ); - - const createPersonalTableSettingsResponse = await request(app.getHttpServer()) - .put(`/settings/personal/${createConnectionRO.id}`) - .query({ tableName: testTableName }) - .send(createPersonalTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(createPersonalTableSettingsResponse.status, 200); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) - .send(createTableSettingsDTO) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(createTableSettingsResponse.status, 201); - - const fieldname = faker.lorem.words(1); - const fieldGtvalue = '25'; - const fieldLtvalue = '40'; - - const getTableRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, - ) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTablesRO = JSON.parse(getTableRowsResponse.text); - t.is(getTablesRO.rows.length, 2); - t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); - t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); - t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTablesRO, 'pagination'), true); - } catch (e) { - console.error(e); - throw e; - } - }, + `${currentTest} should return an array with searched fields when filtered name passed in request is incorrect`, + async (t) => { + try { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName } = await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + createConnectionRO.id, + testTableName, + [testTableColumnName], + undefined, + undefined, + undefined, + undefined, + undefined, + undefined, + ); + + const createPersonalTableSettingsDTO = mockFactory.generatePersonalTableSettingsDto( + undefined, + 3, + QueryOrderingEnum.DESC, + 'id', + ); + + const createPersonalTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings/personal/${createConnectionRO.id}`) + .query({ tableName: testTableName }) + .send(createPersonalTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createPersonalTableSettingsResponse.status, 200); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${createConnectionRO.id}&tableName=${testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const fieldname = faker.lorem.words(1); + const fieldGtvalue = '25'; + const fieldLtvalue = '40'; + + const getTableRowsResponse = await request(app.getHttpServer()) + .get( + `/table/rows/${createConnectionRO.id}?tableName=${testTableName}&search=${testSearchedUserName}&page=1&perPage=2&f_${fieldname}__lt=${fieldLtvalue}&f_${fieldname}__gt=${fieldGtvalue}`, + ) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTablesRO = JSON.parse(getTableRowsResponse.text); + t.is(getTablesRO.rows.length, 2); + t.is(getTablesRO.rows[0][testTableColumnName], testSearchedUserName); + t.is(getTablesRO.rows[1][testTableColumnName], testSearchedUserName); + t.is(Object.hasOwn(getTablesRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTablesRO, 'pagination'), true); + } catch (e) { + console.error(e); + throw e; + } + }, ); currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 200); - const getTableStructureRO = JSON.parse(getTableStructure.text); - - t.is(typeof getTableStructureRO, 'object'); - t.is(typeof getTableStructureRO.structure, 'object'); - t.is(getTableStructureRO.structure.length, 5); - - for (const element of getTableStructureRO.structure) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'column_default'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - t.is(Object.hasOwn(element, 'isExcluded'), true); - t.is(Object.hasOwn(element, 'isSearched'), true); - } - - t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); - - for (const element of getTableStructureRO.primaryColumns) { - t.is(Object.hasOwn(element, 'column_name'), true); - t.is(Object.hasOwn(element, 'data_type'), true); - } - - for (const element of getTableStructureRO.foreignKeys) { - t.is(Object.hasOwn(element, 'referenced_column_name'), true); - t.is(Object.hasOwn(element, 'referenced_table_name'), true); - t.is(Object.hasOwn(element, 'constraint_name'), true); - t.is(Object.hasOwn(element, 'column_name'), true); - } + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 200); + const getTableStructureRO = JSON.parse(getTableStructure.text); + + t.is(typeof getTableStructureRO, 'object'); + t.is(typeof getTableStructureRO.structure, 'object'); + t.is(getTableStructureRO.structure.length, 5); + + for (const element of getTableStructureRO.structure) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'column_default'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + t.is(Object.hasOwn(element, 'isExcluded'), true); + t.is(Object.hasOwn(element, 'isSearched'), true); + } + + t.is(Object.hasOwn(getTableStructureRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); + + for (const element of getTableStructureRO.primaryColumns) { + t.is(Object.hasOwn(element, 'column_name'), true); + t.is(Object.hasOwn(element, 'data_type'), true); + } + + for (const element of getTableStructureRO.foreignKeys) { + t.is(Object.hasOwn(element, 'referenced_column_name'), true); + t.is(Object.hasOwn(element, 'referenced_table_name'), true); + t.is(Object.hasOwn(element, 'constraint_name'), true); + t.is(Object.hasOwn(element, 'column_name'), true); + } }); test.serial(`${currentTest} should throw an exception whe connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - createConnectionRO.id = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + createConnectionRO.id = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 404); }); test.serial(`${currentTest} should throw an exception whe connection id passed in request id incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - createConnectionRO.id = faker.string.uuid(); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 403); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + createConnectionRO.id = faker.string.uuid(); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 403); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest}should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = ''; - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = ''; + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const tableName = faker.lorem.words(1); - const getTableStructure = await request(app.getHttpServer()) - .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableStructure.status, 400); - const { message } = JSON.parse(getTableStructure.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const tableName = faker.lorem.words(1); + const getTableStructure = await request(app.getHttpServer()) + .get(`/table/structure/${createConnectionRO.id}?tableName=${tableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableStructure.status, 400); + const { message } = JSON.parse(getTableStructure.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should add row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addRowInTableRO = JSON.parse(addRowInTableResponse.text); - t.is(addRowInTableResponse.status, 201); - - t.is(Object.hasOwn(addRowInTableRO, 'row'), true); - t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); - t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 43); - t.is(rows[42][testTableColumnName], row[testTableColumnName]); - t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); - t.is(rows[42].id, rows[41].id + 1); - - // check that rows adding was logged - - const getLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getLogsResponse.status, 200); - const getLogsRO = JSON.parse(getLogsResponse.text); - t.is(Object.hasOwn(getLogsRO, 'logs'), true); - t.is(Object.hasOwn(getLogsRO, 'pagination'), true); - t.is(getLogsRO.logs.length > 0, true); - const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); - t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); - t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); - t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, 43); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addRowInTableRO = JSON.parse(addRowInTableResponse.text); + t.is(addRowInTableResponse.status, 201); + + t.is(Object.hasOwn(addRowInTableRO, 'row'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + t.is(addRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(addRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 43); + t.is(rows[42][testTableColumnName], row[testTableColumnName]); + t.is(rows[42][testTableSecondColumnName], row[testTableSecondColumnName]); + t.is(rows[42].id, rows[41].id + 1); + + // check that rows adding was logged + + const getLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getLogsResponse.status, 200); + const getLogsRO = JSON.parse(getLogsResponse.text); + t.is(Object.hasOwn(getLogsRO, 'logs'), true); + t.is(Object.hasOwn(getLogsRO, 'pagination'), true); + t.is(getLogsRO.logs.length > 0, true); + const addRowLogIndex = getLogsRO.logs.findIndex((log) => log.operationType === 'addRow'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex], 'affected_primary_key'), true); + t.is(typeof getLogsRO.logs[addRowLogIndex].affected_primary_key, 'object'); + t.is(Object.hasOwn(getLogsRO.logs[addRowLogIndex].affected_primary_key, 'id'), true); + t.is(getLogsRO.logs[addRowLogIndex].affected_primary_key.id, 43); }); test.serial(`${currentTest} should throw an exception when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - const fakeConnectionId = ''; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 404); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + const fakeConnectionId = ''; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${testTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 404); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when row is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.PARAMETER_MISSING); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.PARAMETER_MISSING); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - id: 999, - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTableResponse = await request(app.getHttpServer()) - .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(addRowInTableResponse.status, 400); - const { message } = JSON.parse(addRowInTableResponse.text); - - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't added - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + id: 999, + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTableResponse = await request(app.getHttpServer()) + .post(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTableResponse.status, 400); + const { message } = JSON.parse(addRowInTableResponse.text); + + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't added + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); }); currentTest = 'PUT /table/row/:slug'; test.serial(`${currentTest} should update row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 200); - const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); - - t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); - t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); - t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); - - //checking that the line was updated - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - const updateRowIndex = rows.map((row) => row.id).indexOf(1); - t.is(rows.length, 42); - t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); - t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 200); + const updateRowInTableRO = JSON.parse(updateRowInTableResponse.text); + + t.is(Object.hasOwn(updateRowInTableRO, 'row'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(updateRowInTableRO, 'readonly_fields'), true); + t.is(updateRowInTableRO.row[testTableColumnName], row[testTableColumnName]); + t.is(updateRowInTableRO.row[testTableSecondColumnName], row[testTableSecondColumnName]); + + //checking that the line was updated + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + const updateRowIndex = rows.map((row) => row.id).indexOf(1); + t.is(rows.length, 42); + t.is(rows[updateRowIndex][testTableColumnName], row[testTableColumnName]); + t.is(rows[updateRowIndex][testTableSecondColumnName], row[testTableSecondColumnName]); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = ''; - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = ''; + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 404); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 403); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 403); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - createConnectionRO.id = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + createConnectionRO.id = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const fakeTableName = faker.string.uuid(); - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const fakeTableName = faker.string.uuid(); + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&IncorrectField=1`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const fakeName = faker.person.firstName(); - const fakeMail = faker.internet.email(); - - const row = { - [testTableColumnName]: fakeName, - [testTableSecondColumnName]: fakeMail, - }; - - const updateRowInTableResponse = await request(app.getHttpServer()) - .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) - .send(JSON.stringify(row)) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(updateRowInTableResponse.status, 400); - const { message } = JSON.parse(updateRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const fakeName = faker.person.firstName(); + const fakeMail = faker.internet.email(); + + const row = { + [testTableColumnName]: fakeName, + [testTableSecondColumnName]: fakeMail, + }; + + const updateRowInTableResponse = await request(app.getHttpServer()) + .put(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000000`) + .send(JSON.stringify(row)) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(updateRowInTableResponse.status, 400); + const { message } = JSON.parse(updateRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 200); - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - - t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 41); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, true); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 200); + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + + t.is(Object.hasOwn(deleteRowInTableRO, 'row'), true); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 41); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, true); }); test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 404); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 404); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const connectionId = faker.string.uuid(); - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 403); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const connectionId = faker.string.uuid(); + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${connectionId}?tableName=${testTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 403); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = ''; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = ''; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForDeletion}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial(`${currentTest} should throw an exception when primary key not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); }); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForDeletion = 1; - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowInTableResponse.status, 400); - const { message } = JSON.parse(deleteRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - - //checking that the line wasn't deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, 42); - const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); - t.is(deletedRowIndex < 0, false); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForDeletion = 1; + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakePKey=1`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTableResponse.status, 400); + const { message } = JSON.parse(deleteRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + + //checking that the line wasn't deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, 42); + const deletedRowIndex = rows.map((row: Record) => row.id).indexOf(idForDeletion); + t.is(deletedRowIndex < 0, false); + }, ); test.serial( - `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const deleteRowInTableResponse = await request(app.getHttpServer()) - .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); - t.is(deleteRowInTableResponse.status, 400); - t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception when primary key passed in request has incorrect field value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const deleteRowInTableResponse = await request(app.getHttpServer()) + .delete(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=100000`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const deleteRowInTableRO = JSON.parse(deleteRowInTableResponse.text); + t.is(deleteRowInTableResponse.status, 400); + t.is(deleteRowInTableRO.message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} found row`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 200); - const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); - t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); - t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); - t.is(typeof foundRowInTableRO.row, 'object'); - t.is(typeof foundRowInTableRO.structure, 'object'); - t.is(typeof foundRowInTableRO.primaryColumns, 'object'); - t.is(typeof foundRowInTableRO.readonly_fields, 'object'); - t.is(typeof foundRowInTableRO.foreignKeys, 'object'); - t.is(foundRowInTableRO.row.id, 1); - t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); - t.is(Object.keys(foundRowInTableRO.row).length, 5); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 200); + const foundRowInTableRO = JSON.parse(foundRowInTableResponse.text); + t.is(Object.hasOwn(foundRowInTableRO, 'row'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(foundRowInTableRO, 'readonly_fields'), true); + t.is(typeof foundRowInTableRO.row, 'object'); + t.is(typeof foundRowInTableRO.structure, 'object'); + t.is(typeof foundRowInTableRO.primaryColumns, 'object'); + t.is(typeof foundRowInTableRO.readonly_fields, 'object'); + t.is(typeof foundRowInTableRO.foreignKeys, 'object'); + t.is(foundRowInTableRO.row.id, 1); + t.is(foundRowInTableRO.row[testTableColumnName], testSearchedUserName); + t.is(Object.keys(foundRowInTableRO.row).length, 5); }); test.serial(`${currentTest} should throw an exception, when connection id is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const idForSearch = 1; - createConnectionRO.id = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 404); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const idForSearch = 1; + createConnectionRO.id = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 404); }); test.serial( - `${currentTest} should throw an exception, when connection id passed in request is incorrect`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - createConnectionRO.id = faker.string.uuid(); - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 403); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.DONT_HAVE_PERMISSIONS); - }, + `${currentTest} should throw an exception, when connection id passed in request is incorrect`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + createConnectionRO.id = faker.string.uuid(); + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 403); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.DONT_HAVE_PERMISSIONS); + }, ); test.serial(`${currentTest} should throw an exception, when tableName in not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = ''; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NAME_MISSING); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = ''; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NAME_MISSING); }); test.serial(`${currentTest} should throw an exception, when tableName passed in request is incorrect`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.TABLE_NOT_FOUND); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${fakeTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.TABLE_NOT_FOUND); }); test.serial(`${currentTest} should throw an exception, when primary key is not passed in request`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); }); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.PRIMARY_KEY_INVALID); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect name`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&fakeKeyName=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.PRIMARY_KEY_INVALID); + }, ); test.serial( - `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, - async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - - const idForSearch = 1000000; - const foundRowInTableResponse = await request(app.getHttpServer()) - .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(foundRowInTableResponse.status, 400); - const { message } = JSON.parse(foundRowInTableResponse.text); - t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); - }, + `${currentTest} should throw an exception, when primary key passed in request has incorrect value`, + async (t) => { + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + + const idForSearch = 1000000; + const foundRowInTableResponse = await request(app.getHttpServer()) + .get(`/table/row/${createConnectionRO.id}?tableName=${testTableName}&id=${idForSearch}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(foundRowInTableResponse.status, 400); + const { message } = JSON.parse(foundRowInTableResponse.text); + t.is(message, Messages.ROW_PRIMARY_KEY_NOT_FOUND); + }, ); currentTest = 'PUT /table/rows/delete/:slug'; test.serial(`${currentTest} should delete row in table and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = - await createTestPostgresTableWithSchema(connectionToTestDB); - - testTables.push(testTableName); - - const createConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createConnectionRO = JSON.parse(createConnectionResponse.text); - t.is(createConnectionResponse.status, 201); - const primaryKeysForDeletion: Array> = [ - { - id: 1, - }, - { - id: 10, - }, - { - id: 32, - }, - ]; - const deleteRowsInTableResponse = await request(app.getHttpServer()) - .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) - .send(primaryKeysForDeletion) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(deleteRowsInTableResponse.status, 200); - const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); - - //checking that the line was deleted - const getTableRowsResponse = await request(app.getHttpServer()) - .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(getTableRowsResponse.status, 200); - - const getTableRowsRO = JSON.parse(getTableRowsResponse.text); - - t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); - t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); - t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); - // check that lines was deleted - - const { rows, primaryColumns, pagination } = getTableRowsRO; - - t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); - - for (const key of primaryKeysForDeletion) { - t.is( - rows.findIndex((row) => row.id === key.id), - -1, - ); - } - - // check that table deletaion was logged - const tableLogsResponse = await request(app.getHttpServer()) - .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(tableLogsResponse.status, 200); - - const tableLogsRO = JSON.parse(tableLogsResponse.text); - t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); - const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); - for (const key of primaryKeysForDeletion) { - t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); - } + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + const { testTableName, testTableColumnName, testEntitiesSeedsCount, testTableSecondColumnName } = + await createTestPostgresTableWithSchema(connectionToTestDB); + + testTables.push(testTableName); + + const createConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createConnectionRO = JSON.parse(createConnectionResponse.text); + t.is(createConnectionResponse.status, 201); + const primaryKeysForDeletion: Array> = [ + { + id: 1, + }, + { + id: 10, + }, + { + id: 32, + }, + ]; + const deleteRowsInTableResponse = await request(app.getHttpServer()) + .put(`/table/rows/delete/${createConnectionRO.id}?tableName=${testTableName}`) + .send(primaryKeysForDeletion) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowsInTableResponse.status, 200); + const _deleteRowInTableRO = JSON.parse(deleteRowsInTableResponse.text); + + //checking that the line was deleted + const getTableRowsResponse = await request(app.getHttpServer()) + .get(`/table/rows/${createConnectionRO.id}?tableName=${testTableName}&page=1&perPage=50`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRowsResponse.status, 200); + + const getTableRowsRO = JSON.parse(getTableRowsResponse.text); + + t.is(Object.hasOwn(getTableRowsRO, 'rows'), true); + t.is(Object.hasOwn(getTableRowsRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getTableRowsRO, 'pagination'), true); + // check that lines was deleted + + const { rows, primaryColumns, pagination } = getTableRowsRO; + + t.is(rows.length, testEntitiesSeedsCount - primaryKeysForDeletion.length); + + for (const key of primaryKeysForDeletion) { + t.is( + rows.findIndex((row) => row.id === key.id), + -1, + ); + } + + // check that table deletaion was logged + const tableLogsResponse = await request(app.getHttpServer()) + .get(`/logs/${createConnectionRO.id}?tableName=${testTableName}`) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(tableLogsResponse.status, 200); + + const tableLogsRO = JSON.parse(tableLogsResponse.text); + t.is(tableLogsRO.logs.length, primaryKeysForDeletion.length + 1); + const onlyDeleteLogs = tableLogsRO.logs.filter((log) => log.operationType === LogOperationTypeEnum.deleteRow); + for (const key of primaryKeysForDeletion) { + t.is(onlyDeleteLogs.findIndex((log) => log.received_data.id === key.id) >= 0, true); + } }); test.serial(`${currentTest} should test connection and return result`, async (t) => { - const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; - const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - - const testConnectionResponse = await request(app.getHttpServer()) - .post('/connection/test/') - .send(connectionToTestDB) - .set('Cookie', firstUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(testConnectionResponse.status, 201); - const { message } = JSON.parse(testConnectionResponse.text); - t.is(message, 'Successfully connected'); + const connectionToTestDB = getTestData(mockFactory).connectionToPostgresSchema; + const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; + + const testConnectionResponse = await request(app.getHttpServer()) + .post('/connection/test/') + .send(connectionToTestDB) + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(testConnectionResponse.status, 201); + const { message } = JSON.parse(testConnectionResponse.text); + t.is(message, 'Successfully connected'); }); diff --git a/backend/test/ava-tests/saas-tests/table-widgets-e2e.test.ts b/backend/test/ava-tests/saas-tests/table-widgets-e2e.test.ts index d5a5d71cc..25b2d540d 100644 --- a/backend/test/ava-tests/saas-tests/table-widgets-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/table-widgets-e2e.test.ts @@ -1,48 +1,43 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { - DynamoDB, - PutItemCommand, - PutItemCommandInput, -} from "@aws-sdk/client-dynamodb"; -import { DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb"; -import { faker } from "@faker-js/faker"; -import { INestApplication, ValidationPipe } from "@nestjs/common"; -import { Test } from "@nestjs/testing"; -import test from "ava"; -import { ValidationError } from "class-validator"; -import cookieParser from "cookie-parser"; -import ibmdb from "ibm_db"; -import JSON5 from "json5"; -import { MongoClient } from "mongodb"; -import request from "supertest"; -import { ApplicationModule } from "../../../src/app.module.js"; -import { WinstonLogger } from "../../../src/entities/logging/winston-logger.js"; -import { CreateOrUpdateTableWidgetsDto } from "../../../src/entities/widget/dto/create-table-widget.dto.js"; -import { WidgetTypeEnum } from "../../../src/enums/widget-type.enum.js"; -import { AllExceptionsFilter } from "../../../src/exceptions/all-exceptions.filter.js"; -import { ValidationException } from "../../../src/exceptions/custom-exceptions/validation-exception.js"; -import { Messages } from "../../../src/exceptions/text/messages.js"; -import { Cacher } from "../../../src/helpers/cache/cacher.js"; -import { DatabaseModule } from "../../../src/shared/database/database.module.js"; -import { DatabaseService } from "../../../src/shared/database/database.service.js"; -import { MockFactory } from "../../mock.factory.js"; -import { compareTableWidgetsArrays } from "../../utils/compare-table-widgets-arrays.js"; -import { createTestTable } from "../../utils/create-test-table.js"; -import { getRandomTestTableName } from "../../utils/get-random-test-table-name.js"; -import { getTestData } from "../../utils/get-test-data.js"; -import { getTestKnex } from "../../utils/get-test-knex.js"; -import { registerUserAndReturnUserInfo } from "../../utils/register-user-and-return-user-info.js"; -import { TestUtils } from "../../utils/test.utils.js"; +import { DynamoDB, PutItemCommand, PutItemCommandInput } from '@aws-sdk/client-dynamodb'; +import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb'; +import { faker } from '@faker-js/faker'; +import { INestApplication, ValidationPipe } from '@nestjs/common'; +import { Test } from '@nestjs/testing'; +import test from 'ava'; +import { ValidationError } from 'class-validator'; +import cookieParser from 'cookie-parser'; +import ibmdb from 'ibm_db'; +import JSON5 from 'json5'; +import { MongoClient } from 'mongodb'; +import request from 'supertest'; +import { ApplicationModule } from '../../../src/app.module.js'; +import { WinstonLogger } from '../../../src/entities/logging/winston-logger.js'; +import { CreateOrUpdateTableWidgetsDto } from '../../../src/entities/widget/dto/create-table-widget.dto.js'; +import { WidgetTypeEnum } from '../../../src/enums/widget-type.enum.js'; +import { AllExceptionsFilter } from '../../../src/exceptions/all-exceptions.filter.js'; +import { ValidationException } from '../../../src/exceptions/custom-exceptions/validation-exception.js'; +import { Messages } from '../../../src/exceptions/text/messages.js'; +import { Cacher } from '../../../src/helpers/cache/cacher.js'; +import { DatabaseModule } from '../../../src/shared/database/database.module.js'; +import { DatabaseService } from '../../../src/shared/database/database.service.js'; +import { MockFactory } from '../../mock.factory.js'; +import { compareTableWidgetsArrays } from '../../utils/compare-table-widgets-arrays.js'; +import { createTestTable } from '../../utils/create-test-table.js'; +import { getRandomTestTableName } from '../../utils/get-random-test-table-name.js'; +import { getTestData } from '../../utils/get-test-data.js'; +import { getTestKnex } from '../../utils/get-test-knex.js'; +import { registerUserAndReturnUserInfo } from '../../utils/register-user-and-return-user-info.js'; +import { TestUtils } from '../../utils/test.utils.js'; const mockFactory = new MockFactory(); let app: INestApplication; let _testUtils: TestUtils; let currentTest; -const tableNameForWidgets = "connection"; +const tableNameForWidgets = 'connection'; -const _uuidRegex: RegExp = - /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i; +const _uuidRegex: RegExp = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-5][0-9a-f]{3}-[089ab][0-9a-f]{3}-[0-9a-f]{12}$/i; test.before(async () => { const moduleFixture = await Test.createTestingModule({ @@ -70,58 +65,49 @@ test.after(async () => { await Cacher.clearAllCache(); await app.close(); } catch (e) { - console.error("After tests error " + e); + console.error('After tests error ' + e); } }); -currentTest = "GET /widgets/:slug"; +currentTest = 'GET /widgets/:slug'; -test.serial( - `${currentTest} should return empty array, table widgets not created`, - async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const newConnection = getTestData(mockFactory).newEncryptedConnection; - const createdConnection = await request(app.getHttpServer()) - .post("/connection") - .send(newConnection) - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should return empty array, table widgets not created`, async (t) => { + const { token } = await registerUserAndReturnUserInfo(app); + const newConnection = getTestData(mockFactory).newEncryptedConnection; + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const connectionId = JSON.parse(createdConnection.text).id; + const connectionId = JSON.parse(createdConnection.text).id; - const getTableWidgets = await request(app.getHttpServer()) - .get(`/widgets/${connectionId}?tableName=${tableNameForWidgets}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${connectionId}?tableName=${tableNameForWidgets}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(getTableWidgets.status, 200); - t.is(typeof getTableWidgetsRO, "object"); - t.is(getTableWidgetsRO.length, 0); - }, -); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(getTableWidgets.status, 200); + t.is(typeof getTableWidgetsRO, 'object'); + t.is(getTableWidgetsRO.length, 0); +}); test.skip(`${currentTest} should return automatically created widgets array, if table contains specific data`, async (t) => { const connectionToTestDB = getTestData(mockFactory).connectionToPostgres; const firstUserToken = (await registerUserAndReturnUserInfo(app)).token; - const { testTableName } = await createTestTable( - connectionToTestDB, - undefined, - undefined, - false, - true, - ); + const { testTableName } = await createTestTable(connectionToTestDB, undefined, undefined, false, true); const createdConnection = await request(app.getHttpServer()) - .post("/connection") + .post('/connection') .send(connectionToTestDB) - .set("Cookie", firstUserToken) - .set("masterpwd", "ahalaimahalai") - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', firstUserToken) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createdConnection.status, 201); const connectionId = JSON.parse(createdConnection.text).id; @@ -132,351 +118,305 @@ test.skip(`${currentTest} should return automatically created widgets array, if const getTableWidgets = await request(app.getHttpServer()) .get(`/widgets/${connectionId}?tableName=${testTableName}`) - .set("Content-Type", "application/json") - .set("Cookie", firstUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', firstUserToken) + .set('Accept', 'application/json'); const foundRows = await request(app.getHttpServer()) .get(`/table/rows/${connectionId}?tableName=${testTableName}`) - .set("Cookie", firstUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', firstUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(foundRows.status, 200); const _foundRowsRO = JSON.parse(foundRows.text); const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(typeof getTableWidgetsRO, "object"); + t.is(typeof getTableWidgetsRO, 'object'); t.is(getTableWidgets.status, 200); t.is(getTableWidgetsRO.length, 8); - const phoneWidget = getTableWidgetsRO.find( - (w) => w.widget_type === WidgetTypeEnum.Phone, - ); + const phoneWidget = getTableWidgetsRO.find((w) => w.widget_type === WidgetTypeEnum.Phone); t.truthy(phoneWidget); - const uuidWidget = getTableWidgetsRO.find( - (w) => w.widget_type === WidgetTypeEnum.UUID, - ); + const uuidWidget = getTableWidgetsRO.find((w) => w.widget_type === WidgetTypeEnum.UUID); t.truthy(uuidWidget); - const countryCodeWidget = getTableWidgetsRO.find( - (w) => w.widget_type === WidgetTypeEnum.Country, - ); + const countryCodeWidget = getTableWidgetsRO.find((w) => w.widget_type === WidgetTypeEnum.Country); t.truthy(countryCodeWidget); - const emailWidget = getTableWidgetsRO.find( - (w) => w.widget_type === WidgetTypeEnum.String, - ); + const emailWidget = getTableWidgetsRO.find((w) => w.widget_type === WidgetTypeEnum.String); t.truthy(emailWidget); t.is(emailWidget.widget_params.includes('"validate": "isEmail"'), true); - const urlWidget = getTableWidgetsRO.find( - (w) => w.widget_type === WidgetTypeEnum.URL, - ); + const urlWidget = getTableWidgetsRO.find((w) => w.widget_type === WidgetTypeEnum.URL); t.truthy(urlWidget); - const foundColorWIdgets = getTableWidgetsRO.filter( - (w) => w.widget_type === WidgetTypeEnum.Color, - ); + const foundColorWIdgets = getTableWidgetsRO.filter((w) => w.widget_type === WidgetTypeEnum.Color); t.is(foundColorWIdgets.length, 3); }); -test.serial( - `${currentTest} should return array of table widgets for table`, - async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const newConnection = getTestData(mockFactory).newEncryptedConnection; - const createdConnection = await request(app.getHttpServer()) - .post("/connection") - .send(newConnection) - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - const connectionId = JSON.parse(createdConnection.text).id; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); - const createTableWidgetResponse = await request(app.getHttpServer()) - .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) - .send({ widgets: newTableWidgets }) - .set("Cookie", token) - .set("Content-Type", "application/json") - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 201); +test.serial(`${currentTest} should return array of table widgets for table`, async (t) => { + const { token } = await registerUserAndReturnUserInfo(app); + const newConnection = getTestData(mockFactory).newEncryptedConnection; + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(Array.isArray(createTableWidgetRO), true); - t.is(createTableWidgetRO.length, newTableWidgets.length); - t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); - t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); - t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); + const connectionId = JSON.parse(createdConnection.text).id; + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) + .send({ widgets: newTableWidgets }) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 201); - t.is(createTableWidgetRO[0].description, newTableWidgets[0].description); + t.is(Array.isArray(createTableWidgetRO), true); + t.is(createTableWidgetRO.length, newTableWidgets.length); + t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); + t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); + t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); - const getTableWidgets = await request(app.getHttpServer()) - .get(`/widgets/${connectionId}?tableName=${tableNameForWidgets}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); - t.is(getTableWidgets.status, 200); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(typeof getTableWidgetsRO, "object"); - t.is(getTableWidgetsRO.length, 2); + t.is(createTableWidgetRO[0].description, newTableWidgets[0].description); - t.is(getTableWidgetsRO[0].field_name, newTableWidgets[0].field_name); - t.is(getTableWidgetsRO[1].widget_type, newTableWidgets[1].widget_type); + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${connectionId}?tableName=${tableNameForWidgets}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getTableWidgets.status, 200); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(typeof getTableWidgetsRO, 'object'); + t.is(getTableWidgetsRO.length, 2); - const getTableStructureResponse = await request(app.getHttpServer()) - .get(`/table/structure/${connectionId}?tableName=${tableNameForWidgets}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); - t.is(getTableStructureResponse.status, 200); - const getTableStructureRO = JSON.parse(getTableStructureResponse.text); - t.is(Object.hasOwn(getTableStructureRO, "table_widgets"), true); - t.is(getTableStructureRO.table_widgets.length, 2); - t.is( - getTableStructureRO.table_widgets[0].field_name, - newTableWidgets[0].field_name, - ); - t.is( - getTableStructureRO.table_widgets[1].widget_type, - newTableWidgets[1].widget_type, - ); - t.is( - compareTableWidgetsArrays( - getTableStructureRO.table_widgets, - newTableWidgets, - ), - true, - ); - }, -); + t.is(getTableWidgetsRO[0].field_name, newTableWidgets[0].field_name); + t.is(getTableWidgetsRO[1].widget_type, newTableWidgets[1].widget_type); + + const getTableStructureResponse = await request(app.getHttpServer()) + .get(`/table/structure/${connectionId}?tableName=${tableNameForWidgets}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getTableStructureResponse.status, 200); + const getTableStructureRO = JSON.parse(getTableStructureResponse.text); + t.is(Object.hasOwn(getTableStructureRO, 'table_widgets'), true); + t.is(getTableStructureRO.table_widgets.length, 2); + t.is(getTableStructureRO.table_widgets[0].field_name, newTableWidgets[0].field_name); + t.is(getTableStructureRO.table_widgets[1].widget_type, newTableWidgets[1].widget_type); + t.is(compareTableWidgetsArrays(getTableStructureRO.table_widgets, newTableWidgets), true); +}); -test.serial( - `${currentTest} should throw exception when connection id not passed in request`, - async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const newConnection = getTestData(mockFactory).newEncryptedConnection; - const createdConnection = await request(app.getHttpServer()) - .post("/connection") - .send(newConnection) - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw exception when connection id not passed in request`, async (t) => { + const { token } = await registerUserAndReturnUserInfo(app); + const newConnection = getTestData(mockFactory).newEncryptedConnection; + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const connectionId = JSON.parse(createdConnection.text).id; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); - const createTableWidgetResponse = await request(app.getHttpServer()) - .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) - .send({ widgets: newTableWidgets }) - .set("Cookie", token) - .set("Content-Type", "application/json") - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 201); + const connectionId = JSON.parse(createdConnection.text).id; + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) + .send({ widgets: newTableWidgets }) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 201); - t.is(Array.isArray(createTableWidgetRO), true); - t.is(createTableWidgetRO.length, newTableWidgets.length); - t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); - t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); - t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); + t.is(Array.isArray(createTableWidgetRO), true); + t.is(createTableWidgetRO.length, newTableWidgets.length); + t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); + t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); + t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); - t.is(createTableWidgetRO[0].description, newTableWidgets[0].description); + t.is(createTableWidgetRO[0].description, newTableWidgets[0].description); - const emptyConnectionId = ""; - const getTableWidgets = await request(app.getHttpServer()) - .get(`/widgets/${emptyConnectionId}?tableName=${tableNameForWidgets}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); - t.is(getTableWidgets.status, 404); - }, -); + const emptyConnectionId = ''; + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${emptyConnectionId}?tableName=${tableNameForWidgets}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getTableWidgets.status, 404); +}); -test.serial( - `${currentTest} should throw exception when connection id passed in request is incorrect`, - async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const newConnection = getTestData(mockFactory).newEncryptedConnection; - const createdConnection = await request(app.getHttpServer()) - .post("/connection") - .send(newConnection) - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw exception when connection id passed in request is incorrect`, async (t) => { + const { token } = await registerUserAndReturnUserInfo(app); + const newConnection = getTestData(mockFactory).newEncryptedConnection; + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const connectionId = JSON.parse(createdConnection.text).id; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); - const createTableWidgetResponse = await request(app.getHttpServer()) - .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 201); + const connectionId = JSON.parse(createdConnection.text).id; + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 201); - t.is(Array.isArray(createTableWidgetRO), true); - t.is(createTableWidgetRO.length, newTableWidgets.length); - t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); - t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); - t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); + t.is(Array.isArray(createTableWidgetRO), true); + t.is(createTableWidgetRO.length, newTableWidgets.length); + t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); + t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); + t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); - t.is(createTableWidgetRO[0].description, newTableWidgets[0].description); + t.is(createTableWidgetRO[0].description, newTableWidgets[0].description); - const fakeConnectionId = faker.string.uuid(); - const getTableWidgets = await request(app.getHttpServer()) - .get(`/widgets/${fakeConnectionId}?tableName=${tableNameForWidgets}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); + const fakeConnectionId = faker.string.uuid(); + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${fakeConnectionId}?tableName=${tableNameForWidgets}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); - t.is(getTableWidgets.status, 403); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(getTableWidgetsRO.message, Messages.DONT_HAVE_PERMISSIONS); - }, -); + t.is(getTableWidgets.status, 403); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(getTableWidgetsRO.message, Messages.DONT_HAVE_PERMISSIONS); +}); -test.serial( - `${currentTest} should throw exception when tableName passed in request is incorrect`, - async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const newConnection = getTestData(mockFactory).newEncryptedConnection; - const createdConnection = await request(app.getHttpServer()) - .post("/connection") - .send(newConnection) - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw exception when tableName passed in request is incorrect`, async (t) => { + const { token } = await registerUserAndReturnUserInfo(app); + const newConnection = getTestData(mockFactory).newEncryptedConnection; + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const connectionId = JSON.parse(createdConnection.text).id; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); - const createTableWidgetResponse = await request(app.getHttpServer()) - .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 201); + const connectionId = JSON.parse(createdConnection.text).id; + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 201); - t.is(Array.isArray(createTableWidgetRO), true); - t.is(createTableWidgetRO.length, newTableWidgets.length); - t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); - t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); - t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); + t.is(Array.isArray(createTableWidgetRO), true); + t.is(createTableWidgetRO.length, newTableWidgets.length); + t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); + t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); + t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); - t.is(createTableWidgetRO[0].description, newTableWidgets[0].description); + t.is(createTableWidgetRO[0].description, newTableWidgets[0].description); - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTableWidgets = await request(app.getHttpServer()) - .get(`/widgets/${connectionId}?tableName=${fakeTableName}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${connectionId}?tableName=${fakeTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(getTableWidgets.status, 400); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(getTableWidgets.status, 400); - t.is(getTableWidgetsRO.message, Messages.TABLE_NOT_FOUND); - }, -); + t.is(getTableWidgetsRO.message, Messages.TABLE_NOT_FOUND); +}); -test.serial( - `${currentTest} should throw exception when tableName not passed in request`, - async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const newConnection = getTestData(mockFactory).newEncryptedConnection; - const createdConnection = await request(app.getHttpServer()) - .post("/connection") - .send(newConnection) - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw exception when tableName not passed in request`, async (t) => { + const { token } = await registerUserAndReturnUserInfo(app); + const newConnection = getTestData(mockFactory).newEncryptedConnection; + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const connectionId = JSON.parse(createdConnection.text).id; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); - const createTableWidgetResponse = await request(app.getHttpServer()) - .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 201); + const connectionId = JSON.parse(createdConnection.text).id; + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 201); - t.is(Array.isArray(createTableWidgetRO), true); - t.is(createTableWidgetRO.length, newTableWidgets.length); - t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); - t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); - t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); + t.is(Array.isArray(createTableWidgetRO), true); + t.is(createTableWidgetRO.length, newTableWidgets.length); + t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); + t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); + t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); - t.is(createTableWidgetRO[0].description, newTableWidgets[0].description); + t.is(createTableWidgetRO[0].description, newTableWidgets[0].description); - const fakeTableName = ""; - const getTableWidgets = await request(app.getHttpServer()) - .get(`/widgets/${connectionId}?tableName=${fakeTableName}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); + const fakeTableName = ''; + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${connectionId}?tableName=${fakeTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(getTableWidgets.status, 400); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(getTableWidgets.status, 400); - t.is(getTableWidgetsRO.message, Messages.TABLE_NAME_MISSING); - }, -); + t.is(getTableWidgetsRO.message, Messages.TABLE_NAME_MISSING); +}); -currentTest = "POST /widget/:slug"; +currentTest = 'POST /widget/:slug'; test.serial(`${currentTest} should return created table widgets`, async (t) => { const { token } = await registerUserAndReturnUserInfo(app); const newConnection = getTestData(mockFactory).newEncryptedConnection; const createdConnection = await request(app.getHttpServer()) - .post("/connection") + .post('/connection') .send(newConnection) - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); const connectionId = JSON.parse(createdConnection.text).id; - const newTableWidget = - mockFactory.generateCreateWidgetDTOForConnectionTable(); + const newTableWidget = mockFactory.generateCreateWidgetDTOForConnectionTable(); const createTableWidgetResponse = await request(app.getHttpServer()) .post(`/widget/${connectionId}?tableName=connection`) .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); const _createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 201); const getTableWidgets = await request(app.getHttpServer()) .get(`/widgets/${connectionId}?tableName=connection`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); t.is(getTableWidgets.status, 200); const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(typeof getTableWidgetsRO, "object"); + t.is(typeof getTableWidgetsRO, 'object'); t.is(getTableWidgetsRO.length, 2); t.is(getTableWidgetsRO[0].widget_type, newTableWidget.widget_type); @@ -487,188 +427,173 @@ test.serial(`${currentTest} hould return updated table widgets`, async (t) => { const { token } = await registerUserAndReturnUserInfo(app); const newConnection = getTestData(mockFactory).newEncryptedConnection; const createdConnection = await request(app.getHttpServer()) - .post("/connection") + .post('/connection') .send(newConnection) - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const connectionId = JSON.parse(createdConnection.text).id; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); const createTableWidgetResponse = await request(app.getHttpServer()) .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); const _createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 201); - const updatedTableWidgets = - mockFactory.generateUpdateWidgetDTOsArrayForConnectionTable(); + const updatedTableWidgets = mockFactory.generateUpdateWidgetDTOsArrayForConnectionTable(); const updateTableWidgetResponse = await request(app.getHttpServer()) .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) .send({ widgets: updatedTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); const _updateTableWidgetRO = JSON.parse(updateTableWidgetResponse.text); t.is(updateTableWidgetResponse.status, 201); const getTableWidgets = await request(app.getHttpServer()) .get(`/widgets/${connectionId}?tableName=${tableNameForWidgets}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); t.is(getTableWidgets.status, 200); const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(typeof getTableWidgetsRO, "object"); + t.is(typeof getTableWidgetsRO, 'object'); t.is(getTableWidgetsRO.length, 2); t.is(getTableWidgetsRO[0].widget_type, updatedTableWidgets[0].widget_type); t.is(compareTableWidgetsArrays(getTableWidgetsRO, updatedTableWidgets), true); }); -test.serial( - `${currentTest} should return updated table widgets when old widget updated and new added`, - async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const newConnection = getTestData(mockFactory).newEncryptedConnection; - const createdConnection = await request(app.getHttpServer()) - .post("/connection") - .send(newConnection) - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); - const connectionId = JSON.parse(createdConnection.text).id; - newTableWidgets.shift(); - const createTableWidgetResponse = await request(app.getHttpServer()) - .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); - const _createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 201); - const updatedTableWidgets = - mockFactory.generateUpdateWidgetDTOsArrayForConnectionTable(); - const updateTableWidgetResponse = await request(app.getHttpServer()) - .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) - .send({ widgets: updatedTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); - const _updateTableWidgetRO = JSON.parse(updateTableWidgetResponse.text); +test.serial(`${currentTest} should return updated table widgets when old widget updated and new added`, async (t) => { + const { token } = await registerUserAndReturnUserInfo(app); + const newConnection = getTestData(mockFactory).newEncryptedConnection; + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); + const connectionId = JSON.parse(createdConnection.text).id; + newTableWidgets.shift(); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const _createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 201); + const updatedTableWidgets = mockFactory.generateUpdateWidgetDTOsArrayForConnectionTable(); + const updateTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) + .send({ widgets: updatedTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const _updateTableWidgetRO = JSON.parse(updateTableWidgetResponse.text); - t.is(updateTableWidgetResponse.status, 201); + t.is(updateTableWidgetResponse.status, 201); - const getTableWidgets = await request(app.getHttpServer()) - .get(`/widgets/${connectionId}?tableName=${tableNameForWidgets}`) - .set("Content-Type", "application/json") - .set("masterpwd", "ahalaimahalai") - .set("Cookie", token) - .set("Accept", "application/json"); - t.is(getTableWidgets.status, 200); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(typeof getTableWidgetsRO, "object"); - t.is(getTableWidgetsRO.length, 2); + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${connectionId}?tableName=${tableNameForWidgets}`) + .set('Content-Type', 'application/json') + .set('masterpwd', 'ahalaimahalai') + .set('Cookie', token) + .set('Accept', 'application/json'); + t.is(getTableWidgets.status, 200); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(typeof getTableWidgetsRO, 'object'); + t.is(getTableWidgetsRO.length, 2); - t.is(getTableWidgetsRO[0].widget_type, updatedTableWidgets[0].widget_type); + t.is(getTableWidgetsRO[0].widget_type, updatedTableWidgets[0].widget_type); - t.is( - compareTableWidgetsArrays(getTableWidgetsRO, updatedTableWidgets), - true, - ); - }, -); + t.is(compareTableWidgetsArrays(getTableWidgetsRO, updatedTableWidgets), true); +}); -test.serial( - `${currentTest} should return table widgets without deleted widget`, - async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const newConnection = getTestData(mockFactory).newEncryptedConnection; - const createdConnection = await request(app.getHttpServer()) - .post("/connection") - .send(newConnection) - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should return table widgets without deleted widget`, async (t) => { + const { token } = await registerUserAndReturnUserInfo(app); + const newConnection = getTestData(mockFactory).newEncryptedConnection; + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const connectionId = JSON.parse(createdConnection.text).id; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); - const createTableWidgetResponse = await request(app.getHttpServer()) - .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); - const _createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 201); + const connectionId = JSON.parse(createdConnection.text).id; + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const _createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 201); - const copyWidgets = [...newTableWidgets]; - copyWidgets.splice(1, 1); + const copyWidgets = [...newTableWidgets]; + copyWidgets.splice(1, 1); - const updateTableWidgetResponse = await request(app.getHttpServer()) - .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) - .send({ widgets: copyWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); - const updateTableWidgetRO = JSON.parse(updateTableWidgetResponse.text); - t.is(updateTableWidgetRO.length, 1); + const updateTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) + .send({ widgets: copyWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const updateTableWidgetRO = JSON.parse(updateTableWidgetResponse.text); + t.is(updateTableWidgetRO.length, 1); - t.is(updateTableWidgetResponse.status, 201); + t.is(updateTableWidgetResponse.status, 201); - const getTableWidgets = await request(app.getHttpServer()) - .get(`/widgets/${connectionId}?tableName=${tableNameForWidgets}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); - t.is(getTableWidgets.status, 200); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(typeof getTableWidgetsRO, "object"); - t.is(getTableWidgetsRO.length, 1); - }, -); + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${connectionId}?tableName=${tableNameForWidgets}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(getTableWidgets.status, 200); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(typeof getTableWidgetsRO, 'object'); + t.is(getTableWidgetsRO.length, 1); +}); test.skip(`${currentTest} should throw exception when table widget with incorrect type passed in request`, async (t) => { const { token } = await registerUserAndReturnUserInfo(app); const newConnection = getTestData(mockFactory).newEncryptedConnection; const createdConnection = await request(app.getHttpServer()) - .post("/connection") + .post('/connection') .send(newConnection) - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const connectionId = JSON.parse(createdConnection.text).id; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); const copyWidgets = [...newTableWidgets]; copyWidgets[0].widget_type = faker.lorem.words(1); const createTableWidgetResponse = await request(app.getHttpServer()) .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) .send({ widgets: copyWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 400); t.is(createTableWidgetRO.message, Messages.WIDGET_TYPE_INCORRECT); @@ -680,154 +605,134 @@ test.serial( const { token } = await registerUserAndReturnUserInfo(app); const newConnection = getTestData(mockFactory).newEncryptedConnection; const createdConnection = await request(app.getHttpServer()) - .post("/connection") + .post('/connection') .send(newConnection) - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const connectionId = JSON.parse(createdConnection.text).id; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); const copyWidgets = [...newTableWidgets]; copyWidgets[0].field_name = faker.lorem.words(1); const createTableWidgetResponse = await request(app.getHttpServer()) .post(`/widget/${connectionId}?tableName=${tableNameForWidgets}`) .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 400); - t.is( - createTableWidgetRO.message, - Messages.EXCLUDED_OR_NOT_EXISTS(copyWidgets[0].field_name), - ); + t.is(createTableWidgetRO.message, Messages.EXCLUDED_OR_NOT_EXISTS(copyWidgets[0].field_name)); }, ); -test.serial( - `${currentTest} should throw exception when connection id not passed in request`, - async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const newConnection = getTestData(mockFactory).newEncryptedConnection; - const createdConnection = await request(app.getHttpServer()) - .post("/connection") - .send(newConnection) - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - const _connectionId = JSON.parse(createdConnection.text).id; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); - const emptyId = ""; - const createTableWidgetResponse = await request(app.getHttpServer()) - .post(`/widget/${emptyId}?tableName=${tableNameForWidgets}`) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); - t.is(createTableWidgetResponse.status, 404); - }, -); +test.serial(`${currentTest} should throw exception when connection id not passed in request`, async (t) => { + const { token } = await registerUserAndReturnUserInfo(app); + const newConnection = getTestData(mockFactory).newEncryptedConnection; + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const _connectionId = JSON.parse(createdConnection.text).id; + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); + const emptyId = ''; + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${emptyId}?tableName=${tableNameForWidgets}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + t.is(createTableWidgetResponse.status, 404); +}); -test.serial( - `${currentTest} should throw exception when connection id passed in request is incorrect`, - async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const newConnection = getTestData(mockFactory).newEncryptedConnection; - const createdConnection = await request(app.getHttpServer()) - .post("/connection") - .send(newConnection) - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); - const _connectionId = JSON.parse(createdConnection.text).id; - const fakeConnectionId = faker.string.uuid(); - const createTableWidgetResponse = await request(app.getHttpServer()) - .post(`/widget/${fakeConnectionId}?tableName=${tableNameForWidgets}`) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 403); - t.is(createTableWidgetRO.message, Messages.DONT_HAVE_PERMISSIONS); - }, -); +test.serial(`${currentTest} should throw exception when connection id passed in request is incorrect`, async (t) => { + const { token } = await registerUserAndReturnUserInfo(app); + const newConnection = getTestData(mockFactory).newEncryptedConnection; + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); + const _connectionId = JSON.parse(createdConnection.text).id; + const fakeConnectionId = faker.string.uuid(); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${fakeConnectionId}?tableName=${tableNameForWidgets}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 403); + t.is(createTableWidgetRO.message, Messages.DONT_HAVE_PERMISSIONS); +}); -test.serial( - `${currentTest} should throw exception when tableName passed in request is incorrect`, - async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const newConnection = getTestData(mockFactory).newEncryptedConnection; - const createdConnection = await request(app.getHttpServer()) - .post("/connection") - .send(newConnection) - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw exception when tableName passed in request is incorrect`, async (t) => { + const { token } = await registerUserAndReturnUserInfo(app); + const newConnection = getTestData(mockFactory).newEncryptedConnection; + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const connectionId = JSON.parse(createdConnection.text).id; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const connectionId = JSON.parse(createdConnection.text).id; + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const createTableWidgetResponse = await request(app.getHttpServer()) - .post(`/widget/${connectionId}?tableName=${fakeTableName}`) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 400); - t.is(createTableWidgetRO.message, Messages.TABLE_NOT_FOUND); - }, -); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connectionId}?tableName=${fakeTableName}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 400); + t.is(createTableWidgetRO.message, Messages.TABLE_NOT_FOUND); +}); -test.serial( - `${currentTest} should throw exception when tableName not passed in request`, - async (t) => { - const { token } = await registerUserAndReturnUserInfo(app); - const newConnection = getTestData(mockFactory).newEncryptedConnection; - const createdConnection = await request(app.getHttpServer()) - .post("/connection") - .send(newConnection) - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw exception when tableName not passed in request`, async (t) => { + const { token } = await registerUserAndReturnUserInfo(app); + const newConnection = getTestData(mockFactory).newEncryptedConnection; + const createdConnection = await request(app.getHttpServer()) + .post('/connection') + .send(newConnection) + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const connectionId = JSON.parse(createdConnection.text).id; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); - const fakeTableName = ""; - const createTableWidgetResponse = await request(app.getHttpServer()) - .post(`/widget/${connectionId}?tableName=${fakeTableName}`) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("masterpwd", "ahalaimahalai") - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 400); - t.is(createTableWidgetRO.message, Messages.TABLE_NAME_MISSING); - }, -); + const connectionId = JSON.parse(createdConnection.text).id; + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForConnectionTable(); + const fakeTableName = ''; + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connectionId}?tableName=${fakeTableName}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('masterpwd', 'ahalaimahalai') + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 400); + t.is(createTableWidgetRO.message, Messages.TABLE_NAME_MISSING); +}); //foreign key widget tests -currentTest = "POST /widget/:slug/"; +currentTest = 'POST /widget/:slug/'; test.serial( `${currentTest} should return created table widgets for postgres database and return rows with attached foreign entities info`, async (t) => { @@ -837,13 +742,13 @@ test.serial( const connectionParamsCopy = { ...connectionToTestDB, }; - if (connectionToTestDB.type === "mysql") { - connectionParamsCopy.type = "mysql2"; + if (connectionToTestDB.type === 'mysql') { + connectionParamsCopy.type = 'mysql2'; } const Knex = getTestKnex(connectionParamsCopy); const referencedTableTableName = `referenced_table_${faker.string.uuid()}`; - const referencedColumnName = "referenced_on_id"; + const referencedColumnName = 'referenced_on_id'; const secondColumnInReferencedTable = faker.lorem.words(1); await Knex.schema.createTable(referencedTableTableName, (table) => { table.increments(); @@ -866,25 +771,25 @@ test.serial( { widget_type: WidgetTypeEnum.Foreign_key, widget_params: JSON.stringify({ - referenced_column_name: "id", + referenced_column_name: 'id', referenced_table_name: firstTableData.testTableName, - constraint_name: "manually_created_constraint", + constraint_name: 'manually_created_constraint', column_name: referencedColumnName, }), field_name: referencedColumnName, - description: "User ID as foreign key", - name: "User ID", + description: 'User ID as foreign key', + name: 'User ID', widget_options: JSON.stringify({}), }, ], }; const createConnectionResponse = await request(app.getHttpServer()) - .post("/connection") + .post('/connection') .send(connectionToTestDB) - .set("Cookie", token) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const createConnectionRO = JSON.parse(createConnectionResponse.text); t.is(createConnectionResponse.status, 201); const connectionId = createConnectionRO.id; @@ -892,84 +797,62 @@ test.serial( const createTableWidgetResponse = await request(app.getHttpServer()) .post(`/widget/${connectionId}?tableName=${referencedTableTableName}`) .send(foreignKeyWidgetsDTO) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); const _createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 201); const getTableWidgets = await request(app.getHttpServer()) .get(`/widgets/${connectionId}?tableName=${referencedTableTableName}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); t.is(getTableWidgets.status, 200); const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(typeof getTableWidgetsRO, "object"); + t.is(typeof getTableWidgetsRO, 'object'); t.is(getTableWidgetsRO.length, 1); - t.is( - getTableWidgetsRO[0].widget_type, - foreignKeyWidgetsDTO.widgets[0].widget_type, - ); + t.is(getTableWidgetsRO[0].widget_type, foreignKeyWidgetsDTO.widgets[0].widget_type); const getTableStructureResponse = await request(app.getHttpServer()) - .get( - `/table/structure/${connectionId}?tableName=${referencedTableTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .get(`/table/structure/${connectionId}?tableName=${referencedTableTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); const getTableStructureRO = JSON.parse(getTableStructureResponse.text); t.is(getTableStructureResponse.status, 200); - t.is(Object.hasOwn(getTableStructureRO, "table_widgets"), true); + t.is(Object.hasOwn(getTableStructureRO, 'table_widgets'), true); t.is(getTableStructureRO.table_widgets.length, 1); - t.is( - getTableStructureRO.table_widgets[0].field_name, - foreignKeyWidgetsDTO.widgets[0].field_name, - ); - t.is( - getTableStructureRO.table_widgets[0].widget_type, - foreignKeyWidgetsDTO.widgets[0].widget_type, - ); - t.is(Object.hasOwn(getTableStructureRO, "foreignKeys"), true); + t.is(getTableStructureRO.table_widgets[0].field_name, foreignKeyWidgetsDTO.widgets[0].field_name); + t.is(getTableStructureRO.table_widgets[0].widget_type, foreignKeyWidgetsDTO.widgets[0].widget_type); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); t.is(getTableStructureRO.foreignKeys.length, 1); - t.is( - getTableStructureRO.foreignKeys[0].column_name, - foreignKeyWidgetsDTO.widgets[0].field_name, - ); - t.is( - getTableStructureRO.foreignKeys[0].referenced_table_name, - firstTableData.testTableName, - ); - const widgetParams = JSON5.parse( - getTableStructureRO.table_widgets[0].widget_params, - ); + t.is(getTableStructureRO.foreignKeys[0].column_name, foreignKeyWidgetsDTO.widgets[0].field_name); + t.is(getTableStructureRO.foreignKeys[0].referenced_table_name, firstTableData.testTableName); + const widgetParams = JSON5.parse(getTableStructureRO.table_widgets[0].widget_params); t.is(widgetParams.referenced_table_name, firstTableData.testTableName); - t.is(widgetParams.referenced_column_name, "id"); - t.is(widgetParams.constraint_name, "manually_created_constraint"); + t.is(widgetParams.referenced_column_name, 'id'); + t.is(widgetParams.constraint_name, 'manually_created_constraint'); t.is(widgetParams.column_name, referencedColumnName); - t.is( - Object.hasOwn(getTableStructureRO.foreignKeys[0], "autocomplete_columns"), - true, - ); + t.is(Object.hasOwn(getTableStructureRO.foreignKeys[0], 'autocomplete_columns'), true); t.is(getTableStructureRO.foreignKeys[0].autocomplete_columns.length, 5); // check table rows received with foreign keys from widget const getRowsResponse = await request(app.getHttpServer()) .get(`/table/rows/${connectionId}?tableName=${referencedTableTableName}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); t.is(getRowsResponse.status, 200); const getRowsRO = JSON.parse(getRowsResponse.text); - t.is(typeof getRowsRO.rows[0], "object"); + t.is(typeof getRowsRO.rows[0], 'object'); for (const row of getRowsRO.rows) { - t.is(Object.hasOwn(row, "id"), true); + t.is(Object.hasOwn(row, 'id'), true); t.is(Object.hasOwn(row, referencedColumnName), true); - t.is(Object.hasOwn(row[referencedColumnName], "id"), true); + t.is(Object.hasOwn(row[referencedColumnName], 'id'), true); } }, ); @@ -983,13 +866,13 @@ test.serial( const connectionParamsCopy = { ...connectionToTestDB, }; - if (connectionToTestDB.type === "mysql") { - connectionParamsCopy.type = "mysql2"; + if (connectionToTestDB.type === 'mysql') { + connectionParamsCopy.type = 'mysql2'; } const Knex = getTestKnex(connectionParamsCopy); const referencedTableTableName = `referenced_table_${faker.string.uuid()}`; - const referencedColumnName = "referenced_on_id"; + const referencedColumnName = 'referenced_on_id'; const secondColumnInReferencedTable = faker.lorem.words(1); await Knex.schema.createTable(referencedTableTableName, (table) => { table.increments(); @@ -1012,25 +895,25 @@ test.serial( { widget_type: WidgetTypeEnum.Foreign_key, widget_params: JSON.stringify({ - referenced_column_name: "id", + referenced_column_name: 'id', referenced_table_name: firstTableData.testTableName, - constraint_name: "manually_created_constraint", + constraint_name: 'manually_created_constraint', column_name: referencedColumnName, }), field_name: referencedColumnName, - description: "User ID as foreign key", - name: "User ID", + description: 'User ID as foreign key', + name: 'User ID', widget_options: JSON.stringify({}), }, ], }; const createConnectionResponse = await request(app.getHttpServer()) - .post("/connection") + .post('/connection') .send(connectionToTestDB) - .set("Cookie", token) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const createConnectionRO = JSON.parse(createConnectionResponse.text); t.is(createConnectionResponse.status, 201); const connectionId = createConnectionRO.id; @@ -1038,82 +921,60 @@ test.serial( const createTableWidgetResponse = await request(app.getHttpServer()) .post(`/widget/${connectionId}?tableName=${referencedTableTableName}`) .send(foreignKeyWidgetsDTO) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); const _createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 201); const getTableWidgets = await request(app.getHttpServer()) .get(`/widgets/${connectionId}?tableName=${referencedTableTableName}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); t.is(getTableWidgets.status, 200); const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(typeof getTableWidgetsRO, "object"); + t.is(typeof getTableWidgetsRO, 'object'); t.is(getTableWidgetsRO.length, 1); - t.is( - getTableWidgetsRO[0].widget_type, - foreignKeyWidgetsDTO.widgets[0].widget_type, - ); + t.is(getTableWidgetsRO[0].widget_type, foreignKeyWidgetsDTO.widgets[0].widget_type); const getTableStructureResponse = await request(app.getHttpServer()) - .get( - `/table/structure/${connectionId}?tableName=${referencedTableTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .get(`/table/structure/${connectionId}?tableName=${referencedTableTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); const getTableStructureRO = JSON.parse(getTableStructureResponse.text); t.is(getTableStructureResponse.status, 200); - t.is(Object.hasOwn(getTableStructureRO, "table_widgets"), true); + t.is(Object.hasOwn(getTableStructureRO, 'table_widgets'), true); t.is(getTableStructureRO.table_widgets.length, 1); - t.is( - getTableStructureRO.table_widgets[0].field_name, - foreignKeyWidgetsDTO.widgets[0].field_name, - ); - t.is( - getTableStructureRO.table_widgets[0].widget_type, - foreignKeyWidgetsDTO.widgets[0].widget_type, - ); - t.is(Object.hasOwn(getTableStructureRO, "foreignKeys"), true); + t.is(getTableStructureRO.table_widgets[0].field_name, foreignKeyWidgetsDTO.widgets[0].field_name); + t.is(getTableStructureRO.table_widgets[0].widget_type, foreignKeyWidgetsDTO.widgets[0].widget_type); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); t.is(getTableStructureRO.foreignKeys.length, 1); - t.is( - getTableStructureRO.foreignKeys[0].column_name, - foreignKeyWidgetsDTO.widgets[0].field_name, - ); - t.is( - getTableStructureRO.foreignKeys[0].referenced_table_name, - firstTableData.testTableName, - ); - const widgetParams = JSON5.parse( - getTableStructureRO.table_widgets[0].widget_params, - ); + t.is(getTableStructureRO.foreignKeys[0].column_name, foreignKeyWidgetsDTO.widgets[0].field_name); + t.is(getTableStructureRO.foreignKeys[0].referenced_table_name, firstTableData.testTableName); + const widgetParams = JSON5.parse(getTableStructureRO.table_widgets[0].widget_params); t.is(widgetParams.referenced_table_name, firstTableData.testTableName); - t.is(widgetParams.referenced_column_name, "id"); - t.is(widgetParams.constraint_name, "manually_created_constraint"); + t.is(widgetParams.referenced_column_name, 'id'); + t.is(widgetParams.constraint_name, 'manually_created_constraint'); t.is(widgetParams.column_name, referencedColumnName); - t.is( - Object.hasOwn(getTableStructureRO.foreignKeys[0], "autocomplete_columns"), - true, - ); + t.is(Object.hasOwn(getTableStructureRO.foreignKeys[0], 'autocomplete_columns'), true); t.is(getTableStructureRO.foreignKeys[0].autocomplete_columns.length, 5); // check table rows received with foreign keys from widget const getRowsResponse = await request(app.getHttpServer()) .get(`/table/rows/${connectionId}?tableName=${referencedTableTableName}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); t.is(getRowsResponse.status, 200); const getRowsRO = JSON.parse(getRowsResponse.text); - t.is(typeof getRowsRO.rows[0], "object"); + t.is(typeof getRowsRO.rows[0], 'object'); for (const row of getRowsRO.rows) { - t.is(Object.hasOwn(row, "id"), true); + t.is(Object.hasOwn(row, 'id'), true); } }, ); @@ -1127,13 +988,13 @@ test.serial( const connectionParamsCopy = { ...connectionToTestDB, }; - if (connectionToTestDB.type === "mysql") { - connectionParamsCopy.type = "mysql2"; + if (connectionToTestDB.type === 'mysql') { + connectionParamsCopy.type = 'mysql2'; } const Knex = getTestKnex(connectionParamsCopy); const referencedTableTableName = `referenced_table_${faker.string.uuid()}`; - const referencedColumnName = "referenced_on_id"; + const referencedColumnName = 'referenced_on_id'; const secondColumnInReferencedTable = faker.lorem.words(1); await Knex.schema.createTable(referencedTableTableName, (table) => { table.increments(); @@ -1156,25 +1017,25 @@ test.serial( { widget_type: WidgetTypeEnum.Foreign_key, widget_params: JSON.stringify({ - referenced_column_name: "id", + referenced_column_name: 'id', referenced_table_name: firstTableData.testTableName, - constraint_name: "manually_created_constraint", + constraint_name: 'manually_created_constraint', column_name: referencedColumnName, }), field_name: referencedColumnName, - description: "User ID as foreign key", - name: "User ID", + description: 'User ID as foreign key', + name: 'User ID', widget_options: JSON.stringify({}), }, ], }; const createConnectionResponse = await request(app.getHttpServer()) - .post("/connection") + .post('/connection') .send(connectionToTestDB) - .set("Cookie", token) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const createConnectionRO = JSON.parse(createConnectionResponse.text); t.is(createConnectionResponse.status, 201); const connectionId = createConnectionRO.id; @@ -1182,82 +1043,60 @@ test.serial( const createTableWidgetResponse = await request(app.getHttpServer()) .post(`/widget/${connectionId}?tableName=${referencedTableTableName}`) .send(foreignKeyWidgetsDTO) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); const _createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 201); const getTableWidgets = await request(app.getHttpServer()) .get(`/widgets/${connectionId}?tableName=${referencedTableTableName}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); t.is(getTableWidgets.status, 200); const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(typeof getTableWidgetsRO, "object"); + t.is(typeof getTableWidgetsRO, 'object'); t.is(getTableWidgetsRO.length, 1); - t.is( - getTableWidgetsRO[0].widget_type, - foreignKeyWidgetsDTO.widgets[0].widget_type, - ); + t.is(getTableWidgetsRO[0].widget_type, foreignKeyWidgetsDTO.widgets[0].widget_type); const getTableStructureResponse = await request(app.getHttpServer()) - .get( - `/table/structure/${connectionId}?tableName=${referencedTableTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .get(`/table/structure/${connectionId}?tableName=${referencedTableTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); const getTableStructureRO = JSON.parse(getTableStructureResponse.text); t.is(getTableStructureResponse.status, 200); - t.is(Object.hasOwn(getTableStructureRO, "table_widgets"), true); + t.is(Object.hasOwn(getTableStructureRO, 'table_widgets'), true); t.is(getTableStructureRO.table_widgets.length, 1); - t.is( - getTableStructureRO.table_widgets[0].field_name, - foreignKeyWidgetsDTO.widgets[0].field_name, - ); - t.is( - getTableStructureRO.table_widgets[0].widget_type, - foreignKeyWidgetsDTO.widgets[0].widget_type, - ); - t.is(Object.hasOwn(getTableStructureRO, "foreignKeys"), true); + t.is(getTableStructureRO.table_widgets[0].field_name, foreignKeyWidgetsDTO.widgets[0].field_name); + t.is(getTableStructureRO.table_widgets[0].widget_type, foreignKeyWidgetsDTO.widgets[0].widget_type); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); t.is(getTableStructureRO.foreignKeys.length, 1); - t.is( - getTableStructureRO.foreignKeys[0].column_name, - foreignKeyWidgetsDTO.widgets[0].field_name, - ); - t.is( - getTableStructureRO.foreignKeys[0].referenced_table_name, - firstTableData.testTableName, - ); - const widgetParams = JSON5.parse( - getTableStructureRO.table_widgets[0].widget_params, - ); + t.is(getTableStructureRO.foreignKeys[0].column_name, foreignKeyWidgetsDTO.widgets[0].field_name); + t.is(getTableStructureRO.foreignKeys[0].referenced_table_name, firstTableData.testTableName); + const widgetParams = JSON5.parse(getTableStructureRO.table_widgets[0].widget_params); t.is(widgetParams.referenced_table_name, firstTableData.testTableName); - t.is(widgetParams.referenced_column_name, "id"); - t.is(widgetParams.constraint_name, "manually_created_constraint"); + t.is(widgetParams.referenced_column_name, 'id'); + t.is(widgetParams.constraint_name, 'manually_created_constraint'); t.is(widgetParams.column_name, referencedColumnName); - t.is( - Object.hasOwn(getTableStructureRO.foreignKeys[0], "autocomplete_columns"), - true, - ); + t.is(Object.hasOwn(getTableStructureRO.foreignKeys[0], 'autocomplete_columns'), true); t.is(getTableStructureRO.foreignKeys[0].autocomplete_columns.length, 5); // check table rows received with foreign keys from widget const getRowsResponse = await request(app.getHttpServer()) .get(`/table/rows/${connectionId}?tableName=${referencedTableTableName}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); t.is(getRowsResponse.status, 200); const getRowsRO = JSON.parse(getRowsResponse.text); - t.is(typeof getRowsRO.rows[0], "object"); + t.is(typeof getRowsRO.rows[0], 'object'); for (const row of getRowsRO.rows) { - t.is(Object.hasOwn(row, "id"), true); + t.is(Object.hasOwn(row, 'id'), true); } }, ); @@ -1271,13 +1110,13 @@ test.serial( const connectionParamsCopy = { ...connectionToTestDB, }; - if (connectionToTestDB.type === "mysql") { - connectionParamsCopy.type = "mysql2"; + if (connectionToTestDB.type === 'mysql') { + connectionParamsCopy.type = 'mysql2'; } const Knex = getTestKnex(connectionParamsCopy); const referencedTableTableName = `referenced_table_${faker.string.uuid()}`; - const referencedColumnName = "referenced_on_id"; + const referencedColumnName = 'referenced_on_id'; const secondColumnInReferencedTable = faker.lorem.words(1); await Knex.schema.createTable(referencedTableTableName, (table) => { table.increments(); @@ -1300,25 +1139,25 @@ test.serial( { widget_type: WidgetTypeEnum.Foreign_key, widget_params: JSON.stringify({ - referenced_column_name: "id", + referenced_column_name: 'id', referenced_table_name: firstTableData.testTableName, - constraint_name: "manually_created_constraint", + constraint_name: 'manually_created_constraint', column_name: referencedColumnName, }), field_name: referencedColumnName, - description: "User ID as foreign key", - name: "User ID", + description: 'User ID as foreign key', + name: 'User ID', widget_options: JSON.stringify({}), }, ], }; const createConnectionResponse = await request(app.getHttpServer()) - .post("/connection") + .post('/connection') .send(connectionToTestDB) - .set("Cookie", token) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const createConnectionRO = JSON.parse(createConnectionResponse.text); t.is(createConnectionResponse.status, 201); const connectionId = createConnectionRO.id; @@ -1326,82 +1165,60 @@ test.serial( const createTableWidgetResponse = await request(app.getHttpServer()) .post(`/widget/${connectionId}?tableName=${referencedTableTableName}`) .send(foreignKeyWidgetsDTO) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); const _createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 201); const getTableWidgets = await request(app.getHttpServer()) .get(`/widgets/${connectionId}?tableName=${referencedTableTableName}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); t.is(getTableWidgets.status, 200); const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(typeof getTableWidgetsRO, "object"); + t.is(typeof getTableWidgetsRO, 'object'); t.is(getTableWidgetsRO.length, 1); - t.is( - getTableWidgetsRO[0].widget_type, - foreignKeyWidgetsDTO.widgets[0].widget_type, - ); + t.is(getTableWidgetsRO[0].widget_type, foreignKeyWidgetsDTO.widgets[0].widget_type); const getTableStructureResponse = await request(app.getHttpServer()) - .get( - `/table/structure/${connectionId}?tableName=${referencedTableTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .get(`/table/structure/${connectionId}?tableName=${referencedTableTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); const getTableStructureRO = JSON.parse(getTableStructureResponse.text); t.is(getTableStructureResponse.status, 200); - t.is(Object.hasOwn(getTableStructureRO, "table_widgets"), true); + t.is(Object.hasOwn(getTableStructureRO, 'table_widgets'), true); t.is(getTableStructureRO.table_widgets.length, 1); - t.is( - getTableStructureRO.table_widgets[0].field_name, - foreignKeyWidgetsDTO.widgets[0].field_name, - ); - t.is( - getTableStructureRO.table_widgets[0].widget_type, - foreignKeyWidgetsDTO.widgets[0].widget_type, - ); - t.is(Object.hasOwn(getTableStructureRO, "foreignKeys"), true); + t.is(getTableStructureRO.table_widgets[0].field_name, foreignKeyWidgetsDTO.widgets[0].field_name); + t.is(getTableStructureRO.table_widgets[0].widget_type, foreignKeyWidgetsDTO.widgets[0].widget_type); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); t.is(getTableStructureRO.foreignKeys.length, 1); - t.is( - getTableStructureRO.foreignKeys[0].column_name, - foreignKeyWidgetsDTO.widgets[0].field_name, - ); - t.is( - getTableStructureRO.foreignKeys[0].referenced_table_name, - firstTableData.testTableName, - ); - const widgetParams = JSON5.parse( - getTableStructureRO.table_widgets[0].widget_params, - ); + t.is(getTableStructureRO.foreignKeys[0].column_name, foreignKeyWidgetsDTO.widgets[0].field_name); + t.is(getTableStructureRO.foreignKeys[0].referenced_table_name, firstTableData.testTableName); + const widgetParams = JSON5.parse(getTableStructureRO.table_widgets[0].widget_params); t.is(widgetParams.referenced_table_name, firstTableData.testTableName); - t.is(widgetParams.referenced_column_name, "id"); - t.is(widgetParams.constraint_name, "manually_created_constraint"); + t.is(widgetParams.referenced_column_name, 'id'); + t.is(widgetParams.constraint_name, 'manually_created_constraint'); t.is(widgetParams.column_name, referencedColumnName); - t.is( - Object.hasOwn(getTableStructureRO.foreignKeys[0], "autocomplete_columns"), - true, - ); + t.is(Object.hasOwn(getTableStructureRO.foreignKeys[0], 'autocomplete_columns'), true); t.is(getTableStructureRO.foreignKeys[0].autocomplete_columns.length, 5); // check table rows received with foreign keys from widget const getRowsResponse = await request(app.getHttpServer()) .get(`/table/rows/${connectionId}?tableName=${referencedTableTableName}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); t.is(getRowsResponse.status, 200); const getRowsRO = JSON.parse(getRowsResponse.text); - t.is(typeof getRowsRO.rows[0], "object"); + t.is(typeof getRowsRO.rows[0], 'object'); for (const row of getRowsRO.rows) { - t.is(Object.hasOwn(row, "id"), true); + t.is(Object.hasOwn(row, 'id'), true); } }, ); @@ -1415,8 +1232,8 @@ test.serial( const connectionParamsCopy = { ...connectionToTestDB, }; - if (connectionToTestDB.type === "mysql") { - connectionParamsCopy.type = "mysql2"; + if (connectionToTestDB.type === 'mysql') { + connectionParamsCopy.type = 'mysql2'; } const connStr = `DATABASE=${connectionToTestDB.database};HOSTNAME=${connectionToTestDB.host};UID=${connectionToTestDB.username};PWD=${connectionToTestDB.password};PORT=${connectionToTestDB.port};PROTOCOL=TCPIP`; @@ -1424,12 +1241,12 @@ test.serial( await ibmDatabase.open(connStr); const referencedByTableTableName = getRandomTestTableName().toUpperCase(); - const referencedColumnName = "REFERENCED_ON_ID"; + const referencedColumnName = 'REFERENCED_ON_ID'; const queryCheckSchemaExists = `SELECT COUNT(*) FROM SYSCAT.SCHEMATA WHERE SCHEMANAME = '${connectionToTestDB.schema}'`; const schemaExists = await ibmDatabase.query(queryCheckSchemaExists); - if (!schemaExists.length || !schemaExists[0]["1"]) { + if (!schemaExists.length || !schemaExists[0]['1']) { const queryCreateSchema = `CREATE SCHEMA ${connectionToTestDB.schema}`; try { await ibmDatabase.query(queryCreateSchema); @@ -1442,10 +1259,8 @@ test.serial( const queryCheckTableExists = `SELECT COUNT(*) FROM SYSCAT.TABLES WHERE TABNAME = '${referencedByTableTableName}' AND TABSCHEMA = '${connectionToTestDB.schema}'`; const tableExists = await ibmDatabase.query(queryCheckTableExists); - if (tableExists.length && tableExists[0]["1"]) { - await ibmDatabase.query( - `DROP TABLE ${connectionToTestDB.schema}.${referencedByTableTableName}`, - ); + if (tableExists.length && tableExists[0]['1']) { + await ibmDatabase.query(`DROP TABLE ${connectionToTestDB.schema}.${referencedByTableTableName}`); } const testColumnName = `product_description`; @@ -1469,7 +1284,7 @@ test.serial( for (let index = 0; index < 42; index++) { const insertQuery = `INSERT INTO ${ connectionToTestDB.schema - }.${referencedByTableTableName} (${referencedColumnName}, ${testColumnName}, created_at, updated_at) VALUES (${faker.number.int({ min: 1, max: 42 })}, '${faker.lorem.words(1).replace(/["']/g, "")}', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)`; + }.${referencedByTableTableName} (${referencedColumnName}, ${testColumnName}, created_at, updated_at) VALUES (${faker.number.int({ min: 1, max: 42 })}, '${faker.lorem.words(1).replace(/["']/g, '')}', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)`; await ibmDatabase.query(insertQuery); } @@ -1479,122 +1294,98 @@ test.serial( { widget_type: WidgetTypeEnum.Foreign_key, widget_params: JSON.stringify({ - referenced_column_name: "ID", + referenced_column_name: 'ID', referenced_table_name: firstTableData.testTableName, - constraint_name: "manually_created_constraint", + constraint_name: 'manually_created_constraint', column_name: referencedColumnName, }), field_name: referencedColumnName, - description: "User ID as foreign key", - name: "User ID", + description: 'User ID as foreign key', + name: 'User ID', widget_options: JSON.stringify({}), }, ], }; const createConnectionResponse = await request(app.getHttpServer()) - .post("/connection") + .post('/connection') .send(connectionToTestDB) - .set("Cookie", token) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const createConnectionRO = JSON.parse(createConnectionResponse.text); t.is(createConnectionResponse.status, 201); const connectionId = createConnectionRO.id; const findTablesResponse = await request(app.getHttpServer()) .get(`/connection/tables/${connectionId}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); const _findTablesRO = JSON.parse(findTablesResponse.text); t.is(findTablesResponse.status, 200); const createTableWidgetResponse = await request(app.getHttpServer()) .post(`/widget/${connectionId}?tableName=${referencedByTableTableName}`) .send(foreignKeyWidgetsDTO) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); const _createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 201); const getTableWidgets = await request(app.getHttpServer()) .get(`/widgets/${connectionId}?tableName=${referencedByTableTableName}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); t.is(getTableWidgets.status, 200); const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(typeof getTableWidgetsRO, "object"); + t.is(typeof getTableWidgetsRO, 'object'); t.is(getTableWidgetsRO.length, 1); - t.is( - getTableWidgetsRO[0].widget_type, - foreignKeyWidgetsDTO.widgets[0].widget_type, - ); + t.is(getTableWidgetsRO[0].widget_type, foreignKeyWidgetsDTO.widgets[0].widget_type); const getTableStructureResponse = await request(app.getHttpServer()) - .get( - `/table/structure/${connectionId}?tableName=${referencedByTableTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .get(`/table/structure/${connectionId}?tableName=${referencedByTableTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); const getTableStructureRO = JSON.parse(getTableStructureResponse.text); t.is(getTableStructureResponse.status, 200); - t.is(Object.hasOwn(getTableStructureRO, "table_widgets"), true); + t.is(Object.hasOwn(getTableStructureRO, 'table_widgets'), true); t.is(getTableStructureRO.table_widgets.length, 1); - t.is( - getTableStructureRO.table_widgets[0].field_name, - foreignKeyWidgetsDTO.widgets[0].field_name, - ); - t.is( - getTableStructureRO.table_widgets[0].widget_type, - foreignKeyWidgetsDTO.widgets[0].widget_type, - ); - t.is(Object.hasOwn(getTableStructureRO, "foreignKeys"), true); + t.is(getTableStructureRO.table_widgets[0].field_name, foreignKeyWidgetsDTO.widgets[0].field_name); + t.is(getTableStructureRO.table_widgets[0].widget_type, foreignKeyWidgetsDTO.widgets[0].widget_type); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); t.is(getTableStructureRO.foreignKeys.length, 1); - t.is( - getTableStructureRO.foreignKeys[0].column_name, - foreignKeyWidgetsDTO.widgets[0].field_name, - ); - t.is( - getTableStructureRO.foreignKeys[0].referenced_table_name, - firstTableData.testTableName, - ); - const widgetParams = JSON5.parse( - getTableStructureRO.table_widgets[0].widget_params, - ); + t.is(getTableStructureRO.foreignKeys[0].column_name, foreignKeyWidgetsDTO.widgets[0].field_name); + t.is(getTableStructureRO.foreignKeys[0].referenced_table_name, firstTableData.testTableName); + const widgetParams = JSON5.parse(getTableStructureRO.table_widgets[0].widget_params); t.is(widgetParams.referenced_table_name, firstTableData.testTableName); - t.is(widgetParams.referenced_column_name, "ID"); - t.is(widgetParams.constraint_name, "manually_created_constraint"); + t.is(widgetParams.referenced_column_name, 'ID'); + t.is(widgetParams.constraint_name, 'manually_created_constraint'); t.is(widgetParams.column_name, referencedColumnName); - t.is( - Object.hasOwn(getTableStructureRO.foreignKeys[0], "autocomplete_columns"), - true, - ); + t.is(Object.hasOwn(getTableStructureRO.foreignKeys[0], 'autocomplete_columns'), true); t.is(getTableStructureRO.foreignKeys[0].autocomplete_columns.length, 5); // check table rows received with foreign keys from widget const getRowsResponse = await request(app.getHttpServer()) - .get( - `/table/rows/${connectionId}?tableName=${referencedByTableTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .get(`/table/rows/${connectionId}?tableName=${referencedByTableTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); const getRowsRO = JSON.parse(getRowsResponse.text); t.is(getRowsResponse.status, 200); - t.is(typeof getRowsRO.rows[0], "object"); + t.is(typeof getRowsRO.rows[0], 'object'); for (const row of getRowsRO.rows) { - t.is(Object.hasOwn(row, "ID"), true); + t.is(Object.hasOwn(row, 'ID'), true); t.is(Object.hasOwn(row, referencedColumnName), true); - t.is(Object.hasOwn(row[referencedColumnName], "ID"), true); + t.is(Object.hasOwn(row[referencedColumnName], 'ID'), true); } }, ); @@ -1617,8 +1408,8 @@ test.serial( const referencedByTableName = `orders`; const testTableColumnName = `user_name`; const testReferencedColumnsName = `product_description`; - const referencedByColumnName = "user_id"; - const referencedOnColumnName = "_id"; + const referencedByColumnName = 'user_id'; + const referencedOnColumnName = '_id'; const client = new MongoClient(mongoConnectionString); await client.connect(); @@ -1655,23 +1446,23 @@ test.serial( widget_params: JSON.stringify({ referenced_column_name: referencedOnColumnName, referenced_table_name: referencedOnTableTableName, - constraint_name: "manually_created_constraint", + constraint_name: 'manually_created_constraint', column_name: referencedByColumnName, }), field_name: referencedByColumnName, - description: "User ID as foreign key", - name: "User ID", + description: 'User ID as foreign key', + name: 'User ID', widget_options: JSON.stringify({}), }, ], }; const createConnectionResponse = await request(app.getHttpServer()) - .post("/connection") + .post('/connection') .send(connectionToTestDB) - .set("Cookie", token) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const createConnectionRO = JSON.parse(createConnectionResponse.text); t.is(createConnectionResponse.status, 201); const connectionId = createConnectionRO.id; @@ -1679,72 +1470,55 @@ test.serial( const createTableWidgetResponse = await request(app.getHttpServer()) .post(`/widget/${connectionId}?tableName=${referencedByTableName}`) .send(foreignKeyWidgetsDTO) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); const _createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 201); const getTableWidgets = await request(app.getHttpServer()) .get(`/widgets/${connectionId}?tableName=${referencedByTableName}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); t.is(getTableWidgets.status, 200); const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(typeof getTableWidgetsRO, "object"); + t.is(typeof getTableWidgetsRO, 'object'); t.is(getTableWidgetsRO.length, 1); - t.is( - getTableWidgetsRO[0].widget_type, - foreignKeyWidgetsDTO.widgets[0].widget_type, - ); + t.is(getTableWidgetsRO[0].widget_type, foreignKeyWidgetsDTO.widgets[0].widget_type); const getTableStructureResponse = await request(app.getHttpServer()) - .get( - `/table/structure/${connectionId}?tableName=${referencedByTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .get(`/table/structure/${connectionId}?tableName=${referencedByTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); const getTableStructureRO = JSON.parse(getTableStructureResponse.text); t.is(getTableStructureResponse.status, 200); - t.is(Object.hasOwn(getTableStructureRO, "table_widgets"), true); + t.is(Object.hasOwn(getTableStructureRO, 'table_widgets'), true); t.is(getTableStructureRO.table_widgets.length, 1); - t.is( - getTableStructureRO.table_widgets[0].field_name, - foreignKeyWidgetsDTO.widgets[0].field_name, - ); - t.is( - getTableStructureRO.table_widgets[0].widget_type, - foreignKeyWidgetsDTO.widgets[0].widget_type, - ); - t.is(Object.hasOwn(getTableStructureRO, "foreignKeys"), true); + t.is(getTableStructureRO.table_widgets[0].field_name, foreignKeyWidgetsDTO.widgets[0].field_name); + t.is(getTableStructureRO.table_widgets[0].widget_type, foreignKeyWidgetsDTO.widgets[0].widget_type); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); t.is(getTableStructureRO.foreignKeys.length, 1); - t.is( - getTableStructureRO.foreignKeys[0].column_name, - foreignKeyWidgetsDTO.widgets[0].field_name, - ); - t.is( - getTableStructureRO.foreignKeys[0].referenced_table_name, - referencedOnTableTableName, - ); + t.is(getTableStructureRO.foreignKeys[0].column_name, foreignKeyWidgetsDTO.widgets[0].field_name); + t.is(getTableStructureRO.foreignKeys[0].referenced_table_name, referencedOnTableTableName); // check table rows received with foreign keys from widget const getRowsResponse = await request(app.getHttpServer()) .get(`/table/rows/${connectionId}?tableName=${referencedByTableName}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); t.is(getRowsResponse.status, 200); const getRowsRO = JSON.parse(getRowsResponse.text); - t.is(typeof getRowsRO.rows[0], "object"); + t.is(typeof getRowsRO.rows[0], 'object'); for (const row of getRowsRO.rows) { t.is(Object.hasOwn(row, referencedByColumnName), true); - t.is(Object.hasOwn(row[referencedByColumnName], "_id"), true); + t.is(Object.hasOwn(row[referencedByColumnName], '_id'), true); } }, ); @@ -1760,8 +1534,8 @@ test.serial( const referencedByTableName = `orders`; const testTableColumnName = `user_name`; const testReferencedColumnsName = `product_description`; - const referencedByColumnName = "user_id"; - const referencedOnColumnName = "id"; + const referencedByColumnName = 'user_id'; + const referencedOnColumnName = 'id'; const dynamoDb = new DynamoDB({ endpoint: connectionToTestDB.host, @@ -1769,15 +1543,15 @@ test.serial( accessKeyId: connectionToTestDB.username, secretAccessKey: connectionToTestDB.password, }, - region: "localhost", + region: 'localhost', }); const referencedOnTableTableNameTableParams = { TableName: referencedOnTableTableName, KeySchema: [ - { AttributeName: "id", KeyType: "HASH" }, // Primary key + { AttributeName: 'id', KeyType: 'HASH' }, // Primary key ], - AttributeDefinitions: [{ AttributeName: "id", AttributeType: "N" }], + AttributeDefinitions: [{ AttributeName: 'id', AttributeType: 'N' }], ProvisionedThroughput: { ReadCapacityUnits: 5, WriteCapacityUnits: 5, @@ -1787,9 +1561,9 @@ test.serial( const referencedByTableTableNameTableParams = { TableName: referencedByTableName, KeySchema: [ - { AttributeName: "id", KeyType: "HASH" }, // Primary key + { AttributeName: 'id', KeyType: 'HASH' }, // Primary key ], - AttributeDefinitions: [{ AttributeName: "id", AttributeType: "N" }], + AttributeDefinitions: [{ AttributeName: 'id', AttributeType: 'N' }], ProvisionedThroughput: { ReadCapacityUnits: 5, WriteCapacityUnits: 5, @@ -1847,23 +1621,23 @@ test.serial( widget_params: JSON.stringify({ referenced_column_name: referencedOnColumnName, referenced_table_name: referencedOnTableTableName, - constraint_name: "manually_created_constraint", + constraint_name: 'manually_created_constraint', column_name: referencedByColumnName, }), field_name: referencedByColumnName, - description: "User ID as foreign key", - name: "User ID", + description: 'User ID as foreign key', + name: 'User ID', widget_options: JSON.stringify({}), }, ], }; const createConnectionResponse = await request(app.getHttpServer()) - .post("/connection") + .post('/connection') .send(connectionToTestDB) - .set("Cookie", token) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const createConnectionRO = JSON.parse(createConnectionResponse.text); t.is(createConnectionResponse.status, 201); const connectionId = createConnectionRO.id; @@ -1871,74 +1645,57 @@ test.serial( const createTableWidgetResponse = await request(app.getHttpServer()) .post(`/widget/${connectionId}?tableName=${referencedByTableName}`) .send(foreignKeyWidgetsDTO) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); const _createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 201); const getTableWidgets = await request(app.getHttpServer()) .get(`/widgets/${connectionId}?tableName=${referencedByTableName}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); t.is(getTableWidgets.status, 200); const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(typeof getTableWidgetsRO, "object"); + t.is(typeof getTableWidgetsRO, 'object'); t.is(getTableWidgetsRO.length, 1); - t.is( - getTableWidgetsRO[0].widget_type, - foreignKeyWidgetsDTO.widgets[0].widget_type, - ); + t.is(getTableWidgetsRO[0].widget_type, foreignKeyWidgetsDTO.widgets[0].widget_type); const getTableStructureResponse = await request(app.getHttpServer()) - .get( - `/table/structure/${connectionId}?tableName=${referencedByTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .get(`/table/structure/${connectionId}?tableName=${referencedByTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); const getTableStructureRO = JSON.parse(getTableStructureResponse.text); t.is(getTableStructureResponse.status, 200); - t.is(Object.hasOwn(getTableStructureRO, "table_widgets"), true); + t.is(Object.hasOwn(getTableStructureRO, 'table_widgets'), true); t.is(getTableStructureRO.table_widgets.length, 1); - t.is( - getTableStructureRO.table_widgets[0].field_name, - foreignKeyWidgetsDTO.widgets[0].field_name, - ); - t.is( - getTableStructureRO.table_widgets[0].widget_type, - foreignKeyWidgetsDTO.widgets[0].widget_type, - ); - t.is(Object.hasOwn(getTableStructureRO, "foreignKeys"), true); + t.is(getTableStructureRO.table_widgets[0].field_name, foreignKeyWidgetsDTO.widgets[0].field_name); + t.is(getTableStructureRO.table_widgets[0].widget_type, foreignKeyWidgetsDTO.widgets[0].widget_type); + t.is(Object.hasOwn(getTableStructureRO, 'foreignKeys'), true); t.is(getTableStructureRO.foreignKeys.length, 1); - t.is( - getTableStructureRO.foreignKeys[0].column_name, - foreignKeyWidgetsDTO.widgets[0].field_name, - ); - t.is( - getTableStructureRO.foreignKeys[0].referenced_table_name, - referencedOnTableTableName, - ); + t.is(getTableStructureRO.foreignKeys[0].column_name, foreignKeyWidgetsDTO.widgets[0].field_name); + t.is(getTableStructureRO.foreignKeys[0].referenced_table_name, referencedOnTableTableName); // check table rows received with foreign keys from widget const getRowsResponse = await request(app.getHttpServer()) .get(`/table/rows/${connectionId}?tableName=${referencedByTableName}`) - .set("Content-Type", "application/json") - .set("Cookie", token) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', token) + .set('Accept', 'application/json'); const getRowsRO = JSON.parse(getRowsResponse.text); t.is(getRowsResponse.status, 200); - t.is(typeof getRowsRO.rows[0], "object"); + t.is(typeof getRowsRO.rows[0], 'object'); for (const row of getRowsRO.rows) { t.is(Object.hasOwn(row, referencedByColumnName), true); - t.is(Object.hasOwn(row[referencedByColumnName], "id"), true); + t.is(Object.hasOwn(row[referencedByColumnName], 'id'), true); } }, ); diff --git a/backend/test/ava-tests/saas-tests/user-admin-permissions-e2e.test.ts b/backend/test/ava-tests/saas-tests/user-admin-permissions-e2e.test.ts index bceadd356..bd4aac93f 100644 --- a/backend/test/ava-tests/saas-tests/user-admin-permissions-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/user-admin-permissions-e2e.test.ts @@ -1,38 +1,34 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable security/detect-object-injection */ -import { faker } from "@faker-js/faker"; -import { INestApplication, ValidationPipe } from "@nestjs/common"; -import { Test } from "@nestjs/testing"; -import test from "ava"; -import { ValidationError } from "class-validator"; -import cookieParser from "cookie-parser"; -import request from "supertest"; -import { ApplicationModule } from "../../../src/app.module.js"; -import { WinstonLogger } from "../../../src/entities/logging/winston-logger.js"; -import { - AccessLevelEnum, - QueryOrderingEnum, -} from "../../../src/enums/index.js"; -import { AllExceptionsFilter } from "../../../src/exceptions/all-exceptions.filter.js"; -import { ValidationException } from "../../../src/exceptions/custom-exceptions/validation-exception.js"; -import { Messages } from "../../../src/exceptions/text/messages.js"; -import { Cacher } from "../../../src/helpers/cache/cacher.js"; -import { Constants } from "../../../src/helpers/constants/constants.js"; -import { DatabaseModule } from "../../../src/shared/database/database.module.js"; -import { DatabaseService } from "../../../src/shared/database/database.service.js"; -import { MockFactory } from "../../mock.factory.js"; -import { compareTableWidgetsArrays } from "../../utils/compare-table-widgets-arrays.js"; -import { inviteUserInCompanyAndAcceptInvitation } from "../../utils/register-user-and-return-user-info.js"; -import { TestUtils } from "../../utils/test.utils.js"; -import { createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection } from "../../utils/user-with-different-permissions-utils.js"; +import { faker } from '@faker-js/faker'; +import { INestApplication, ValidationPipe } from '@nestjs/common'; +import { Test } from '@nestjs/testing'; +import test from 'ava'; +import { ValidationError } from 'class-validator'; +import cookieParser from 'cookie-parser'; +import request from 'supertest'; +import { ApplicationModule } from '../../../src/app.module.js'; +import { WinstonLogger } from '../../../src/entities/logging/winston-logger.js'; +import { AccessLevelEnum, QueryOrderingEnum } from '../../../src/enums/index.js'; +import { AllExceptionsFilter } from '../../../src/exceptions/all-exceptions.filter.js'; +import { ValidationException } from '../../../src/exceptions/custom-exceptions/validation-exception.js'; +import { Messages } from '../../../src/exceptions/text/messages.js'; +import { Cacher } from '../../../src/helpers/cache/cacher.js'; +import { Constants } from '../../../src/helpers/constants/constants.js'; +import { DatabaseModule } from '../../../src/shared/database/database.module.js'; +import { DatabaseService } from '../../../src/shared/database/database.service.js'; +import { MockFactory } from '../../mock.factory.js'; +import { compareTableWidgetsArrays } from '../../utils/compare-table-widgets-arrays.js'; +import { inviteUserInCompanyAndAcceptInvitation } from '../../utils/register-user-and-return-user-info.js'; +import { TestUtils } from '../../utils/test.utils.js'; +import { createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection } from '../../utils/user-with-different-permissions-utils.js'; let app: INestApplication; let _testUtils: TestUtils; let currentTest: string; const mockFactory = new MockFactory(); -const newConnectionToPostgres = - mockFactory.generateConnectionToTestPostgresDBInDocker(); +const newConnectionToPostgres = mockFactory.generateConnectionToTestPostgresDBInDocker(); test.before(async () => { const moduleFixture = await Test.createTestingModule({ @@ -60,88 +56,79 @@ test.after(async () => { await Cacher.clearAllCache(); await app.close(); } catch (e) { - console.error("After tests error " + e); + console.error('After tests error ' + e); } }); // Connection controller -currentTest = "GET /connections/"; +currentTest = 'GET /connections/'; -test.serial( - `${currentTest} should return connections, where second user have access`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - const findAll = await request(app.getHttpServer()) - .get("/connections") - .set("Content-Type", "application/json") - .set("Cookie", testData.users.simpleUserToken) - .set("Accept", "application/json"); - - t.is(findAll.status, 200); - - const result = findAll.body.connections; - t.is(result.length, 5); - t.is(Object.hasOwn(result[0], "connection"), true); - t.is(Object.hasOwn(result[0], "accessLevel"), true); - t.is(result[0].accessLevel, AccessLevelEnum.edit); - - t.is(Object.hasOwn(result[0], "accessLevel"), true); - t.is(Object.hasOwn(result[0].connection, "host"), true); - t.is(Object.hasOwn(result[0].connection, "host"), true); - t.is(typeof result[0].connection.port, "number"); - t.is(Object.hasOwn(result[0].connection, "port"), true); - t.is(Object.hasOwn(result[0].connection, "username"), true); - t.is(Object.hasOwn(result[0].connection, "database"), true); - t.is(Object.hasOwn(result[0].connection, "sid"), true); - t.is(Object.hasOwn(result[0].connection, "createdAt"), true); - t.is(Object.hasOwn(result[0].connection, "updatedAt"), true); - t.is(Object.hasOwn(result[0].connection, "password"), false); - t.is(Object.hasOwn(result[0].connection, "groups"), false); - t.is(Object.hasOwn(result[0].connection, "author"), false); - const testConnectionsCount = result.filter( - (el: any) => el.connection.isTestConnection, - ).length; - t.is(testConnectionsCount, 4); - } catch (error) { - console.error(error); - throw error; - } - }, -); +test.serial(`${currentTest} should return connections, where second user have access`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const findAll = await request(app.getHttpServer()) + .get('/connections') + .set('Content-Type', 'application/json') + .set('Cookie', testData.users.simpleUserToken) + .set('Accept', 'application/json'); + + t.is(findAll.status, 200); + + const result = findAll.body.connections; + t.is(result.length, 5); + t.is(Object.hasOwn(result[0], 'connection'), true); + t.is(Object.hasOwn(result[0], 'accessLevel'), true); + t.is(result[0].accessLevel, AccessLevelEnum.edit); + + t.is(Object.hasOwn(result[0], 'accessLevel'), true); + t.is(Object.hasOwn(result[0].connection, 'host'), true); + t.is(Object.hasOwn(result[0].connection, 'host'), true); + t.is(typeof result[0].connection.port, 'number'); + t.is(Object.hasOwn(result[0].connection, 'port'), true); + t.is(Object.hasOwn(result[0].connection, 'username'), true); + t.is(Object.hasOwn(result[0].connection, 'database'), true); + t.is(Object.hasOwn(result[0].connection, 'sid'), true); + t.is(Object.hasOwn(result[0].connection, 'createdAt'), true); + t.is(Object.hasOwn(result[0].connection, 'updatedAt'), true); + t.is(Object.hasOwn(result[0].connection, 'password'), false); + t.is(Object.hasOwn(result[0].connection, 'groups'), false); + t.is(Object.hasOwn(result[0].connection, 'author'), false); + const testConnectionsCount = result.filter((el: any) => el.connection.isTestConnection).length; + t.is(testConnectionsCount, 4); + } catch (error) { + console.error(error); + throw error; + } +}); -currentTest = "GET /connection/one/:slug"; +currentTest = 'GET /connection/one/:slug'; test.serial(`${currentTest} should return a found connection`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const searchedConnectionId = testData.connections.firstId; const findOneResponce = await request(app.getHttpServer()) .get(`/connection/one/${searchedConnectionId}`) - .set("Content-Type", "application/json") - .set("Cookie", testData.users.simpleUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', testData.users.simpleUserToken) + .set('Accept', 'application/json'); t.is(findOneResponce.status, 200); const result = findOneResponce.body.connection; t.is(result.title, newConnectionToPostgres.title); - t.is(result.type, "postgres"); + t.is(result.type, 'postgres'); t.is(result.host, newConnectionToPostgres.host); - t.is(typeof result.port, "number"); + t.is(typeof result.port, 'number'); t.is(result.port, newConnectionToPostgres.port); - t.is(result.username, "postgres"); + t.is(result.username, 'postgres'); t.is(result.database, newConnectionToPostgres.database); t.is(result.sid, null); - t.is(Object.hasOwn(result, "createdAt"), true); - t.is(Object.hasOwn(result, "updatedAt"), true); - t.is(Object.hasOwn(result, "password"), false); - t.is(Object.hasOwn(result, "groups"), false); - t.is(Object.hasOwn(result, "author"), false); + t.is(Object.hasOwn(result, 'createdAt'), true); + t.is(Object.hasOwn(result, 'updatedAt'), true); + t.is(Object.hasOwn(result, 'password'), false); + t.is(Object.hasOwn(result, 'groups'), false); + t.is(Object.hasOwn(result, 'author'), false); } catch (error) { console.error(error); throw error; @@ -152,16 +139,13 @@ test.serial( `${currentTest} should throw an exception, when you do not have permission in this connection`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const searchedConnectionId = testData.connections.secondId; const findOneResponce = await request(app.getHttpServer()) .get(`/connection/one/${searchedConnectionId}`) - .set("Content-Type", "application/json") - .set("Cookie", testData.users.simpleUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', testData.users.simpleUserToken) + .set('Accept', 'application/json'); t.is(findOneResponce.status, 200); const findOneRO = JSON.parse(findOneResponce.text); const connectionKeys: Array = Object.keys(findOneRO.connection); @@ -175,35 +159,34 @@ test.serial( }, ); -currentTest = "PUT /connection"; +currentTest = 'PUT /connection'; test.serial(`${currentTest} should return updated connection`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const updateConnection = mockFactory.generateUpdateConnectionDto(); const updateConnectionResponse = await request(app.getHttpServer()) .put(`/connection/${testData.connections.firstId}`) .send(updateConnection) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(updateConnectionResponse.status, 200); const result = updateConnectionResponse.body.connection; - t.is(result.title, "Updated Test Connection"); - t.is(result.type, "postgres"); - t.is(result.host, "testing_nestjs"); - t.is(typeof result.port, "number"); + t.is(result.title, 'Updated Test Connection'); + t.is(result.type, 'postgres'); + t.is(result.host, 'testing_nestjs'); + t.is(typeof result.port, 'number'); t.is(result.port, 5432); - t.is(result.username, "admin"); - t.is(result.database, "testing_nestjs"); + t.is(result.username, 'admin'); + t.is(result.database, 'testing_nestjs'); t.is(result.sid, null); - t.is(Object.hasOwn(result, "createdAt"), true); - t.is(Object.hasOwn(result, "updatedAt"), true); - t.is(Object.hasOwn(result, "password"), false); - t.is(Object.hasOwn(result, "groups"), false); + t.is(Object.hasOwn(result, 'createdAt'), true); + t.is(Object.hasOwn(result, 'updatedAt'), true); + t.is(Object.hasOwn(result, 'password'), false); + t.is(Object.hasOwn(result, 'groups'), false); } catch (error) { console.error(error); throw error; @@ -214,23 +197,17 @@ test.serial( `${currentTest} should return throw an exception, when you try update a connection without permissions in it`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const updateConnection = mockFactory.generateUpdateConnectionDto(); const updateConnectionResponse = await request(app.getHttpServer()) .put(`/connection/${testData.connections.secondId}`) .send(updateConnection) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(updateConnectionResponse.status, 403); - t.is( - JSON.parse(updateConnectionResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + t.is(JSON.parse(updateConnectionResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); } catch (error) { console.error(error); throw error; @@ -238,27 +215,26 @@ test.serial( }, ); -currentTest = "DELETE /connection/:slug"; +currentTest = 'DELETE /connection/:slug'; test.serial(`${currentTest} should return delete result`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const response = await request(app.getHttpServer()) .put(`/connection/delete/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const result = response.body; //deleted connection not found in database const findOneResponce = await request(app.getHttpServer()) .get(`/connection/one/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(findOneResponce.status, 400); const { message } = JSON.parse(findOneResponce.text); @@ -266,20 +242,20 @@ test.serial(`${currentTest} should return delete result`, async (t) => { t.is(response.status, 200); - t.is(Object.hasOwn(result, "id"), false); + t.is(Object.hasOwn(result, 'id'), false); t.is(result.title, newConnectionToPostgres.title); - t.is(result.type, "postgres"); + t.is(result.type, 'postgres'); t.is(result.host, newConnectionToPostgres.host); - t.is(typeof result.port, "number"); + t.is(typeof result.port, 'number'); t.is(result.port, newConnectionToPostgres.port); - t.is(result.username, "postgres"); + t.is(result.username, 'postgres'); t.is(result.database, newConnectionToPostgres.database); t.is(result.sid, null); - t.is(Object.hasOwn(result, "createdAt"), true); - t.is(Object.hasOwn(result, "updatedAt"), true); - t.is(Object.hasOwn(result, "password"), false); - t.is(Object.hasOwn(result, "groups"), false); - t.is(Object.hasOwn(result, "author"), false); + t.is(Object.hasOwn(result, 'createdAt'), true); + t.is(Object.hasOwn(result, 'updatedAt'), true); + t.is(Object.hasOwn(result, 'password'), false); + t.is(Object.hasOwn(result, 'groups'), false); + t.is(Object.hasOwn(result, 'author'), false); } catch (error) { console.error(error); throw error; @@ -290,25 +266,22 @@ test.serial( `${currentTest} should throw an exception, when you try to delete connection without permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const response = await request(app.getHttpServer()) .put(`/connection/delete/${testData.connections.secondId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 403); t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); //connection wasn't deleted const findOneResponce = await request(app.getHttpServer()) .get(`/connection/one/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(findOneResponce.status, 200); } catch (error) { @@ -318,26 +291,25 @@ test.serial( }, ); -currentTest = "POST /connection/group/:slug"; +currentTest = 'POST /connection/group/:slug'; test.serial(`${currentTest} should return a created group`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const newGroup1 = mockFactory.generateCreateGroupDto1(); const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) + .set('Cookie', testData.users.simpleUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createGroupResponse.status, 201); const result = JSON.parse(createGroupResponse.text); t.is(result.title, newGroup1.title); - t.is(Object.hasOwn(result, "users"), true); - t.is(typeof result.users, "object"); + t.is(Object.hasOwn(result, 'users'), true); + t.is(typeof result.users, 'object'); t.is(result.users.length, 1); t.is(result.users[0].email, testData.users.simpleUserEmail.toLowerCase()); t.is(result.users[0].isActive, true); @@ -351,23 +323,17 @@ test.serial( `${currentTest} should throw an exception when you try add group in connection without permission in it`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const newGroup1 = mockFactory.generateCreateGroupDto1(); const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${testData.connections.secondId}`) - .set("Cookie", testData.users.simpleUserToken) + .set('Cookie', testData.users.simpleUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createGroupResponse.status, 403); - t.is( - JSON.parse(createGroupResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + t.is(JSON.parse(createGroupResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); } catch (error) { console.error(error); throw error; @@ -375,108 +341,99 @@ test.serial( }, ); -currentTest = "PUT /connection/group/delete/:slug"; +currentTest = 'PUT /connection/group/delete/:slug'; -test.serial( - `${currentTest} should return connection without deleted group result`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - const newGroup1 = mockFactory.generateCreateGroupDto1(); +test.serial(`${currentTest} should return connection without deleted group result`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const newGroup1 = mockFactory.generateCreateGroupDto1(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - // create group in connection - let result = createGroupResponse.body; + // create group in connection + let result = createGroupResponse.body; - t.is(createGroupResponse.status, 201); + t.is(createGroupResponse.status, 201); - t.is(Object.hasOwn(result, "id"), true); - t.is(result.title, newGroup1.title); + t.is(Object.hasOwn(result, 'id'), true); + t.is(result.title, newGroup1.title); - const createGroupRO = JSON.parse(createGroupResponse.text); + const createGroupRO = JSON.parse(createGroupResponse.text); - let response = await request(app.getHttpServer()) - .put(`/connection/group/delete/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send({ groupId: createGroupRO.id }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + let response = await request(app.getHttpServer()) + .put(`/connection/group/delete/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send({ groupId: createGroupRO.id }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - //after deleting group - result = response.body; - t.is(response.status, 200); - t.is(Object.hasOwn(result, "title"), true); - t.is(result.title, createGroupRO.title); - t.is(result.isMain, false); - // check that group was deleted + //after deleting group + result = response.body; + t.is(response.status, 200); + t.is(Object.hasOwn(result, 'title'), true); + t.is(result.title, createGroupRO.title); + t.is(result.isMain, false); + // check that group was deleted - response = await request(app.getHttpServer()) - .get(`/connection/groups/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + response = await request(app.getHttpServer()) + .get(`/connection/groups/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(response.status, 200); - result = JSON.parse(response.text); - t.is(result.length, 1); - const _groupId = result[0].group.id; + t.is(response.status, 200); + result = JSON.parse(response.text); + t.is(result.length, 1); + const _groupId = result[0].group.id; - t.is(Object.hasOwn(result[0].group, "title"), true); - t.is(result[0].accessLevel, AccessLevelEnum.edit); + t.is(Object.hasOwn(result[0].group, 'title'), true); + t.is(result[0].accessLevel, AccessLevelEnum.edit); - const index = result.findIndex((el: any) => { - return el.group.title === "Admin"; - }); + const index = result.findIndex((el: any) => { + return el.group.title === 'Admin'; + }); - t.is(index >= 0, true); - } catch (error) { - console.error(error); - throw error; - } - }, -); + t.is(index >= 0, true); + } catch (error) { + console.error(error); + throw error; + } +}); test.serial( `${currentTest} should throw an exception, when you try delete group in connection without permissions`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const newGroup1 = mockFactory.generateCreateGroupDto1(); const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${testData.connections.secondId}`) - .set("Cookie", testData.users.adminUserToken) + .set('Cookie', testData.users.adminUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); // create group in connection const result = createGroupResponse.body; t.is(createGroupResponse.status, 201); - t.is(Object.hasOwn(result, "id"), true); + t.is(Object.hasOwn(result, 'id'), true); t.is(result.title, newGroup1.title); const createGroupRO = JSON.parse(createGroupResponse.text); const response = await request(app.getHttpServer()) .put(`/connection/group/delete/${testData.connections.secondId}`) - .set("Cookie", testData.users.simpleUserToken) + .set('Cookie', testData.users.simpleUserToken) .send({ groupId: createGroupRO.id }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 403); t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); @@ -487,37 +444,36 @@ test.serial( }, ); -currentTest = "GET /connection/groups/:slug"; +currentTest = 'GET /connection/groups/:slug'; test.serial(`${currentTest} return should groups in connection`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const newGroup1 = mockFactory.generateCreateGroupDto1(); const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) + .set('Cookie', testData.users.simpleUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createGroupResponse.status, 201); const response = await request(app.getHttpServer()) .get(`/connection/groups/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 200); const result = JSON.parse(response.text); const _groupId = result[0].group.id; - t.is(Object.hasOwn(result[1].group, "title"), true); + t.is(Object.hasOwn(result[1].group, 'title'), true); t.is(result[0].accessLevel, AccessLevelEnum.edit); - const index = result.findIndex((el: any) => el.group.title === "Admin"); + const index = result.findIndex((el: any) => el.group.title === 'Admin'); t.is(index >= 0, true); } catch (error) { @@ -530,26 +486,23 @@ test.serial( `${currentTest} it should throw an exception, when you try get groups in connection, where you do not have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const newGroup1 = mockFactory.generateCreateGroupDto1(); const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${testData.connections.secondId}`) - .set("Cookie", testData.users.adminUserToken) + .set('Cookie', testData.users.adminUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createGroupResponse.status, 201); const response = await request(app.getHttpServer()) .get(`/connection/groups/${testData.connections.secondId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 200); const result = JSON.parse(response.text); @@ -561,185 +514,158 @@ test.serial( }, ); -currentTest = "GET /connection/permissions"; - -test.serial( - `${currentTest} should return permissions object for current group in current connection`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - const groupId = getGroupsRO[0].group.id; +currentTest = 'GET /connection/permissions'; - const response = await request(app.getHttpServer()) - .get( - `/connection/permissions?connectionId=${testData.connections.firstId}&groupId=${groupId}`, - ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const result = JSON.parse(response.text); - t.is(response.status, 200); +test.serial(`${currentTest} should return permissions object for current group in current connection`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - t.is(Object.hasOwn(result, "connection"), true); - t.is(Object.hasOwn(result, "group"), true); - t.is(Object.hasOwn(result, "tables"), true); - t.is(typeof result.connection, "object"); - t.is(typeof result.group, "object"); - t.is(result.connection.connectionId, testData.connections.firstId); - t.is(result.group.groupId, groupId); - t.is(result.connection.accessLevel, AccessLevelEnum.edit); - t.is(result.group.accessLevel, AccessLevelEnum.edit); - t.is(typeof result.tables, "object"); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const groupId = getGroupsRO[0].group.id; - const { tables } = result; - const tableIndex = tables.findIndex( - (table) => table.tableName === testData.firstTableInfo.testTableName, - ); - t.is(tables.length > 0, true); - t.is(typeof tables[0], "object"); - t.is(Object.hasOwn(tables[tableIndex], "accessLevel"), true); - t.is(tables[tableIndex].accessLevel.visibility, false); - t.is(tables[tableIndex].accessLevel.readonly, false); - t.is(tables[tableIndex].accessLevel.add, false); - t.is(tables[tableIndex].accessLevel.delete, false); - t.is(tables[tableIndex].accessLevel.edit, false); - t.is(tables[tableIndex].accessLevel.readonly, false); - t.is(tables[tableIndex].accessLevel.add, false); - t.is(tables[tableIndex].accessLevel.visibility, false); - t.is(tables[tableIndex].accessLevel.readonly, false); - t.is(tables[tableIndex].accessLevel.edit, false); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const response = await request(app.getHttpServer()) + .get(`/connection/permissions?connectionId=${testData.connections.firstId}&groupId=${groupId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const result = JSON.parse(response.text); + t.is(response.status, 200); -currentTest = "GET /connection/user/permissions"; + t.is(Object.hasOwn(result, 'connection'), true); + t.is(Object.hasOwn(result, 'group'), true); + t.is(Object.hasOwn(result, 'tables'), true); + t.is(typeof result.connection, 'object'); + t.is(typeof result.group, 'object'); + t.is(result.connection.connectionId, testData.connections.firstId); + t.is(result.group.groupId, groupId); + t.is(result.connection.accessLevel, AccessLevelEnum.edit); + t.is(result.group.accessLevel, AccessLevelEnum.edit); + t.is(typeof result.tables, 'object'); + + const { tables } = result; + const tableIndex = tables.findIndex((table) => table.tableName === testData.firstTableInfo.testTableName); + t.is(tables.length > 0, true); + t.is(typeof tables[0], 'object'); + t.is(Object.hasOwn(tables[tableIndex], 'accessLevel'), true); + t.is(tables[tableIndex].accessLevel.visibility, false); + t.is(tables[tableIndex].accessLevel.readonly, false); + t.is(tables[tableIndex].accessLevel.add, false); + t.is(tables[tableIndex].accessLevel.delete, false); + t.is(tables[tableIndex].accessLevel.edit, false); + t.is(tables[tableIndex].accessLevel.readonly, false); + t.is(tables[tableIndex].accessLevel.add, false); + t.is(tables[tableIndex].accessLevel.visibility, false); + t.is(tables[tableIndex].accessLevel.readonly, false); + t.is(tables[tableIndex].accessLevel.edit, false); + } catch (error) { + console.error(error); + throw error; + } +}); -test.serial( - `${currentTest} should return permissions object for current group in current connection`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); +currentTest = 'GET /connection/user/permissions'; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - const groupId = getGroupsRO[0].group.id; +test.serial(`${currentTest} should return permissions object for current group in current connection`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - const response = await request(app.getHttpServer()) - .get( - `/connection/user/permissions?connectionId=${testData.connections.firstId}&groupId=${groupId}`, - ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const groupId = getGroupsRO[0].group.id; - t.is(response.status, 200); - const result = JSON.parse(response.text); + const response = await request(app.getHttpServer()) + .get(`/connection/user/permissions?connectionId=${testData.connections.firstId}&groupId=${groupId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(Object.hasOwn(result, "connection"), true); - t.is(Object.hasOwn(result, "group"), true); - t.is(Object.hasOwn(result, "tables"), true); - t.is(typeof result.connection, "object"); - t.is(typeof result.group, "object"); - t.is(result.connection.connectionId, testData.connections.firstId); - t.is(result.group.groupId, groupId); - t.is(result.connection.accessLevel, AccessLevelEnum.edit); - t.is(result.group.accessLevel, AccessLevelEnum.edit); - t.is(typeof result.tables, "object"); + t.is(response.status, 200); + const result = JSON.parse(response.text); - const { tables } = result; - const tableIndex = tables.findIndex( - (table) => table.tableName === testData.firstTableInfo.testTableName, - ); - t.is(tables.length > 0, true); - t.is(typeof tables[0], "object"); - t.is(Object.hasOwn(tables[tableIndex], "accessLevel"), true); - t.is(tables[tableIndex].accessLevel.visibility, true); - t.is(tables[tableIndex].accessLevel.readonly, false); - t.is(tables[tableIndex].accessLevel.add, true); - t.is(tables[tableIndex].accessLevel.delete, true); - t.is(tables[tableIndex].accessLevel.edit, true); - t.is(tables[tableIndex].accessLevel.readonly, false); - t.is(tables[tableIndex].accessLevel.add, true); - t.is(tables[tableIndex].accessLevel.visibility, true); - t.is(tables[tableIndex].accessLevel.readonly, false); - t.is(tables[tableIndex].accessLevel.edit, true); - } catch (error) { - console.error(error); - throw error; - } - }, -); + t.is(Object.hasOwn(result, 'connection'), true); + t.is(Object.hasOwn(result, 'group'), true); + t.is(Object.hasOwn(result, 'tables'), true); + t.is(typeof result.connection, 'object'); + t.is(typeof result.group, 'object'); + t.is(result.connection.connectionId, testData.connections.firstId); + t.is(result.group.groupId, groupId); + t.is(result.connection.accessLevel, AccessLevelEnum.edit); + t.is(result.group.accessLevel, AccessLevelEnum.edit); + t.is(typeof result.tables, 'object'); + + const { tables } = result; + const tableIndex = tables.findIndex((table) => table.tableName === testData.firstTableInfo.testTableName); + t.is(tables.length > 0, true); + t.is(typeof tables[0], 'object'); + t.is(Object.hasOwn(tables[tableIndex], 'accessLevel'), true); + t.is(tables[tableIndex].accessLevel.visibility, true); + t.is(tables[tableIndex].accessLevel.readonly, false); + t.is(tables[tableIndex].accessLevel.add, true); + t.is(tables[tableIndex].accessLevel.delete, true); + t.is(tables[tableIndex].accessLevel.edit, true); + t.is(tables[tableIndex].accessLevel.readonly, false); + t.is(tables[tableIndex].accessLevel.add, true); + t.is(tables[tableIndex].accessLevel.visibility, true); + t.is(tables[tableIndex].accessLevel.readonly, false); + t.is(tables[tableIndex].accessLevel.edit, true); + } catch (error) { + console.error(error); + throw error; + } +}); test.serial( `${currentTest} should return permissions object for current group in current connection for current user`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const getGroupsResponse = await request(app.getHttpServer()) .get(`/connection/groups/${testData.connections.secondId}`) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); const groupId = getGroupsRO[0].group.id; const response = await request(app.getHttpServer()) - .get( - `/connection/user/permissions?connectionId=${testData.connections.secondId}&groupId=${groupId}`, - ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/connection/user/permissions?connectionId=${testData.connections.secondId}&groupId=${groupId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 200); const result = JSON.parse(response.text); - t.is(Object.hasOwn(result, "connection"), true); - t.is(Object.hasOwn(result, "group"), true); - t.is(Object.hasOwn(result, "tables"), true); - t.is(typeof result.connection, "object"); - t.is(typeof result.group, "object"); + t.is(Object.hasOwn(result, 'connection'), true); + t.is(Object.hasOwn(result, 'group'), true); + t.is(Object.hasOwn(result, 'tables'), true); + t.is(typeof result.connection, 'object'); + t.is(typeof result.group, 'object'); t.is(result.connection.connectionId, testData.connections.secondId); t.is(result.group.groupId, groupId); t.is(result.connection.accessLevel, AccessLevelEnum.none); t.is(result.group.accessLevel, AccessLevelEnum.none); - t.is(typeof result.tables, "object"); + t.is(typeof result.tables, 'object'); const { tables } = result; - const tableIndex = tables.findIndex( - (table) => table.tableName === testData.secondTableInfo.testTableName, - ); + const tableIndex = tables.findIndex((table) => table.tableName === testData.secondTableInfo.testTableName); t.is(tables.length > 0, true); - t.is(typeof tables[0], "object"); - t.is(Object.hasOwn(tables[tableIndex], "accessLevel"), true); + t.is(typeof tables[0], 'object'); + t.is(Object.hasOwn(tables[tableIndex], 'accessLevel'), true); t.is(tables[tableIndex].accessLevel.visibility, false); t.is(tables[tableIndex].accessLevel.readonly, false); t.is(tables[tableIndex].accessLevel.add, false); @@ -754,51 +680,44 @@ test.serial( ); //****************************** GROUP CONTROLLER -currentTest = "GET /groups/"; +currentTest = 'GET /groups/'; -test.serial( - `${currentTest} should return found groups with current user`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); +test.serial(`${currentTest} should return found groups with current user`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/groups/`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - const { groups, groupsCount } = getGroupsRO; - t.is(groupsCount, 1); - t.is(groups.length, 1); - t.is(Object.hasOwn(groups[0], "group"), true); - t.is(Object.hasOwn(groups[0], "accessLevel"), true); - - t.is(Object.hasOwn(groups[0].group, "title"), true); - t.is(Object.hasOwn(groups[0].group, "isMain"), true); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/groups/`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const { groups, groupsCount } = getGroupsRO; + t.is(groupsCount, 1); + t.is(groups.length, 1); + t.is(Object.hasOwn(groups[0], 'group'), true); + t.is(Object.hasOwn(groups[0], 'accessLevel'), true); + + t.is(Object.hasOwn(groups[0].group, 'title'), true); + t.is(Object.hasOwn(groups[0].group, 'isMain'), true); + } catch (error) { + console.error(error); + throw error; + } +}); -currentTest = "GET /group/users/:slug"; +currentTest = 'GET /group/users/:slug'; test.serial(`${currentTest} it should return users in group`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const getGroupsResponse = await request(app.getHttpServer()) .get(`/connection/groups/${testData.connections.firstId}`) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); @@ -806,16 +725,16 @@ test.serial(`${currentTest} it should return users in group`, async (t) => { const response = await request(app.getHttpServer()) .get(`/group/users/${groupId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getUsersRO = JSON.parse(response.text); t.is(getUsersRO.length, 2); t.is(getUsersRO[0].id === getUsersRO[1].id, false); - t.is(Object.hasOwn(getUsersRO[0], "createdAt"), true); - t.is(Object.hasOwn(getUsersRO[0], "password"), false); - t.is(Object.hasOwn(getUsersRO[0], "isActive"), true); - t.is(Object.hasOwn(getUsersRO[0], "email"), true); + t.is(Object.hasOwn(getUsersRO[0], 'createdAt'), true); + t.is(Object.hasOwn(getUsersRO[0], 'password'), false); + t.is(Object.hasOwn(getUsersRO[0], 'isActive'), true); + t.is(Object.hasOwn(getUsersRO[0], 'email'), true); } catch (error) { console.error(error); throw error; @@ -826,16 +745,13 @@ test.serial( `${currentTest} it should throw an exception when you try to receive user in group where you dont have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const getGroupsResponse = await request(app.getHttpServer()) .get(`/connection/groups/${testData.connections.secondId}`) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); @@ -843,9 +759,9 @@ test.serial( const response = await request(app.getHttpServer()) .get(`/group/users/${groupId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getUsersRO = JSON.parse(response.text); t.is(getUsersRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (error) { @@ -855,17 +771,16 @@ test.serial( }, ); -currentTest = "PUT /group/user"; +currentTest = 'PUT /group/user'; test.serial(`${currentTest} should return group with added user`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const getGroupsResponse = await request(app.getHttpServer()) .get(`/connection/groups/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); @@ -882,17 +797,17 @@ test.serial(`${currentTest} should return group with added user`, async (t) => { const email = thirdTestUser.email; const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", testData.users.simpleUserToken) + .put('/group/user') + .set('Cookie', testData.users.simpleUserToken) .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text).group; - t.is(Object.hasOwn(addUserInGroupRO, "title"), true); - t.is(Object.hasOwn(addUserInGroupRO, "isMain"), true); - t.is(Object.hasOwn(addUserInGroupRO, "users"), true); + t.is(Object.hasOwn(addUserInGroupRO, 'title'), true); + t.is(Object.hasOwn(addUserInGroupRO, 'isMain'), true); + t.is(Object.hasOwn(addUserInGroupRO, 'users'), true); const { users } = addUserInGroupRO; t.is(users.length, 3); t.is(users[0].id === users[1].id, false); @@ -904,458 +819,389 @@ test.serial(`${currentTest} should return group with added user`, async (t) => { } }); -test.serial( - `${currentTest} should throw exception, when user email not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw exception, when user email not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const groupId = getGroupsRO[0].group.id; - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", testData.users.simpleUserToken) - .send({ groupId }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const _addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); - t.is(addUserInGroupResponse.status, 400); - // t.is(addUserInGroupRO.message, ErrorsMessages.VALIDATION_FAILED); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const groupId = getGroupsRO[0].group.id; + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', testData.users.simpleUserToken) + .send({ groupId }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const _addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); + t.is(addUserInGroupResponse.status, 400); + // t.is(addUserInGroupRO.message, ErrorsMessages.VALIDATION_FAILED); + } catch (error) { + console.error(error); + throw error; + } +}); -test.serial( - `${currentTest} should throw exception, when group id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw exception, when group id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const _groupId = getGroupsRO[0].group.id; - const email = faker.internet.email(); - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", testData.users.simpleUserToken) - .send({ email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); - t.is(addUserInGroupResponse.status, 400); - t.is(addUserInGroupRO.message, Messages.GROUP_ID_MISSING); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const _groupId = getGroupsRO[0].group.id; + const email = faker.internet.email(); + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', testData.users.simpleUserToken) + .send({ email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); + t.is(addUserInGroupResponse.status, 400); + t.is(addUserInGroupRO.message, Messages.GROUP_ID_MISSING); + } catch (error) { + console.error(error); + throw error; + } +}); -test.serial( - `${currentTest} should throw exception, when group id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); +test.serial(`${currentTest} should throw exception, when group id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); - const _getGroupsRO = JSON.parse(getGroupsResponse.text); - - const email = faker.internet.email(); - const groupId = faker.string.uuid(); - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", testData.users.simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); - t.is(addUserInGroupResponse.status, 400); - t.is(addUserInGroupRO.message, Messages.CONNECTION_NOT_FOUND); - } catch (error) { - console.error(error); - throw error; - } - }, -); + t.is(getGroupsResponse.status, 200); + const _getGroupsRO = JSON.parse(getGroupsResponse.text); -currentTest = "DELETE /group/:slug"; + const email = faker.internet.email(); + const groupId = faker.string.uuid(); + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', testData.users.simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); + t.is(addUserInGroupResponse.status, 400); + t.is(addUserInGroupRO.message, Messages.CONNECTION_NOT_FOUND); + } catch (error) { + console.error(error); + throw error; + } +}); -test.serial( - `${currentTest} should delete result after group deletion`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +currentTest = 'DELETE /group/:slug'; - const newGroup1 = mockFactory.generateCreateGroupDto1(); +test.serial(`${currentTest} should delete result after group deletion`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const newGroup1 = mockFactory.generateCreateGroupDto1(); - t.is(getGroupsResponse.status, 200); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const groupId = JSON.parse(createGroupResponse.text).id; - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/${groupId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteGroupRO = JSON.parse(deleteGroupResponse.text); - t.is(deleteGroupRO.title, newGroup1.title); - t.is(deleteGroupRO.isMain, false); - } catch (error) { - console.error(error); - throw error; - } - }, -); + t.is(getGroupsResponse.status, 200); -test.serial( - `${currentTest} should throw an exception when you try delete admin group`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); + const groupId = JSON.parse(createGroupResponse.text).id; + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/${groupId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteGroupRO = JSON.parse(deleteGroupResponse.text); + t.is(deleteGroupRO.title, newGroup1.title); + t.is(deleteGroupRO.isMain, false); + } catch (error) { + console.error(error); + throw error; + } +}); - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw an exception when you try delete admin group`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const groupId = getGroupsRO[0].group.id; - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/${groupId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteGroupRO = JSON.parse(deleteGroupResponse.text); - t.is(deleteGroupRO.message, Messages.CANT_DELETE_ADMIN_GROUP); - } catch (error) { - console.error(error); - throw error; - } - }, -); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); -test.serial( - `${currentTest} should throw an exception when group id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); + const groupId = getGroupsRO[0].group.id; + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/${groupId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteGroupRO = JSON.parse(deleteGroupResponse.text); + t.is(deleteGroupRO.message, Messages.CANT_DELETE_ADMIN_GROUP); + } catch (error) { + console.error(error); + throw error; + } +}); - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw an exception when group id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - t.is(getGroupsResponse.status, 200); - const _getGroupsRO = JSON.parse(getGroupsResponse.text); - - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(deleteGroupResponse.status, 404); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); -test.serial( - `${currentTest} should throw an exception when group id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); + t.is(getGroupsResponse.status, 200); + const _getGroupsRO = JSON.parse(getGroupsResponse.text); + + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(deleteGroupResponse.status, 404); + } catch (error) { + console.error(error); + throw error; + } +}); - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw an exception when group id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - t.is(getGroupsResponse.status, 200); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const groupId = faker.string.uuid(); - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/${groupId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteGroupRO = JSON.parse(deleteGroupResponse.text); - t.is(deleteGroupRO.message, Messages.CONNECTION_NOT_FOUND); - } catch (error) { - console.error(error); - throw error; - } - }, -); + t.is(getGroupsResponse.status, 200); -currentTest = "PUT /group/user/delete"; + const groupId = faker.string.uuid(); + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/${groupId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteGroupRO = JSON.parse(deleteGroupResponse.text); + t.is(deleteGroupRO.message, Messages.CONNECTION_NOT_FOUND); + } catch (error) { + console.error(error); + throw error; + } +}); -test.serial( - `${currentTest} should return group without deleted user`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); +currentTest = 'PUT /group/user/delete'; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should return group without deleted user`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const groupId = getGroupsRO[0].group.id; + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( - testData.users.adminUserToken, - undefined, - app, - undefined, - ); + const groupId = getGroupsRO[0].group.id; - const email = thirdTestUser.email; - - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", testData.users.simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(addUserInGroupResponse.status, 200); - - const deleteUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user/delete") - .set("Cookie", testData.users.simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); - - t.is(Object.hasOwn(deleteUserInGroupRO, "title"), true); - t.is(Object.hasOwn(deleteUserInGroupRO, "isMain"), true); - t.is(Object.hasOwn(deleteUserInGroupRO, "users"), true); - const { users } = deleteUserInGroupRO; - t.is(users.length, 2); - t.is(users[0].id === users[1].id, false); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( + testData.users.adminUserToken, + undefined, + app, + undefined, + ); -test.serial( - `${currentTest} should throw exception, when user email not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const email = thirdTestUser.email; - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', testData.users.simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addUserInGroupResponse.status, 200); - const groupId = getGroupsRO[0].group.id; + const deleteUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user/delete') + .set('Cookie', testData.users.simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); + + t.is(Object.hasOwn(deleteUserInGroupRO, 'title'), true); + t.is(Object.hasOwn(deleteUserInGroupRO, 'isMain'), true); + t.is(Object.hasOwn(deleteUserInGroupRO, 'users'), true); + const { users } = deleteUserInGroupRO; + t.is(users.length, 2); + t.is(users[0].id === users[1].id, false); + } catch (error) { + console.error(error); + throw error; + } +}); - const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( - testData.users.adminUserToken, - undefined, - app, - undefined, - ); +test.serial(`${currentTest} should throw exception, when user email not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const _email = thirdTestUser.email; + const groupId = getGroupsRO[0].group.id; - const deleteUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user/delete") - .set("Cookie", testData.users.simpleUserToken) - .send({ groupId }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const _deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); - // t.is(deleteUserInGroupRO.message, ErrorsMessages.VALIDATION_FAILED); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( + testData.users.adminUserToken, + undefined, + app, + undefined, + ); -test.serial( - `${currentTest} should throw exception, when group id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const _email = thirdTestUser.email; - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + const deleteUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user/delete') + .set('Cookie', testData.users.simpleUserToken) + .send({ groupId }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const _deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); + // t.is(deleteUserInGroupRO.message, ErrorsMessages.VALIDATION_FAILED); + } catch (error) { + console.error(error); + throw error; + } +}); - const _groupId = getGroupsRO[0].group.id; +test.serial(`${currentTest} should throw exception, when group id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( - testData.users.adminUserToken, - undefined, - app, - undefined, - ); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const email = thirdTestUser.email; + const _groupId = getGroupsRO[0].group.id; - const deleteUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user/delete") - .set("Cookie", testData.users.simpleUserToken) - .send({ email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); - t.is(deleteUserInGroupRO.message, Messages.GROUP_ID_MISSING); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( + testData.users.adminUserToken, + undefined, + app, + undefined, + ); -test.serial( - `${currentTest} should throw exception, when group id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const email = thirdTestUser.email; - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + const deleteUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user/delete') + .set('Cookie', testData.users.simpleUserToken) + .send({ email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); + t.is(deleteUserInGroupRO.message, Messages.GROUP_ID_MISSING); + } catch (error) { + console.error(error); + throw error; + } +}); - let groupId = getGroupsRO[0].group.id; - const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( - testData.users.adminUserToken, - undefined, - app, - undefined, - ); +test.serial(`${currentTest} should throw exception, when group id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const email = thirdTestUser.email; - - groupId = faker.string.uuid(); - const deleteUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user/delete") - .set("Cookie", testData.users.simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); - t.is(deleteUserInGroupRO.message, Messages.CONNECTION_NOT_FOUND); - } catch (error) { - console.error(error); - throw error; - } - }, -); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + + let groupId = getGroupsRO[0].group.id; + const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( + testData.users.adminUserToken, + undefined, + app, + undefined, + ); + + const email = thirdTestUser.email; + + groupId = faker.string.uuid(); + const deleteUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user/delete') + .set('Cookie', testData.users.simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); + t.is(deleteUserInGroupRO.message, Messages.CONNECTION_NOT_FOUND); + } catch (error) { + console.error(error); + throw error; + } +}); //****************************** PERMISSION CONTROLLER -currentTest = "PUT permissions/:slug"; +currentTest = 'PUT permissions/:slug'; test.serial( `${currentTest} should return created complex permissions object when you create permissions`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const newGroup1 = mockFactory.generateCreateGroupDto1(); const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) + .set('Cookie', testData.users.simpleUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const createGroupRO = JSON.parse(createGroupResponse.text); const newGroupId = createGroupRO.id; @@ -1382,32 +1228,17 @@ test.serial( ], }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) .send({ permissions }) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createOrUpdatePermissionRO = JSON.parse( - createOrUpdatePermissionResponse.text, - ); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createOrUpdatePermissionRO = JSON.parse(createOrUpdatePermissionResponse.text); t.is(createOrUpdatePermissionResponse.status, 200); - t.is( - JSON.stringify(createOrUpdatePermissionRO.connection), - JSON.stringify(permissions.connection), - ); - t.is( - JSON.stringify(createOrUpdatePermissionRO.group), - JSON.stringify(permissions.group), - ); - t.is( - JSON.stringify(createOrUpdatePermissionRO.tables), - JSON.stringify(permissions.tables), - ); + t.is(JSON.stringify(createOrUpdatePermissionRO.connection), JSON.stringify(permissions.connection)); + t.is(JSON.stringify(createOrUpdatePermissionRO.group), JSON.stringify(permissions.group)); + t.is(JSON.stringify(createOrUpdatePermissionRO.tables), JSON.stringify(permissions.tables)); } catch (error) { console.error(error); throw error; @@ -1419,17 +1250,14 @@ test.serial( `${currentTest} should return updated complex permissions object when you update permissions`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const newGroup1 = mockFactory.generateCreateGroupDto1(); const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) + .set('Cookie', testData.users.simpleUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const createGroupRO = JSON.parse(createGroupResponse.text); const newGroupId = createGroupRO.id; @@ -1457,30 +1285,17 @@ test.serial( }; let createOrUpdatePermissionResponse = await request(app.getHttpServer()) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) .send({ permissions }) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - let createOrUpdatePermissionRO = JSON.parse( - createOrUpdatePermissionResponse.text, - ); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + let createOrUpdatePermissionRO = JSON.parse(createOrUpdatePermissionResponse.text); JSON.stringify(createOrUpdatePermissionRO); t.is(createOrUpdatePermissionResponse.status, 200); - t.is( - JSON.stringify(createOrUpdatePermissionRO.connection), - JSON.stringify(permissions.connection), - ); - t.is( - JSON.stringify(createOrUpdatePermissionRO.group), - JSON.stringify(permissions.group), - ); - t.is( - JSON.stringify(createOrUpdatePermissionRO.tables), - JSON.stringify(permissions.tables), - ); + t.is(JSON.stringify(createOrUpdatePermissionRO.connection), JSON.stringify(permissions.connection)); + t.is(JSON.stringify(createOrUpdatePermissionRO.group), JSON.stringify(permissions.group)); + t.is(JSON.stringify(createOrUpdatePermissionRO.tables), JSON.stringify(permissions.tables)); //************************ WHEN YOU UPDATE PERMISSIONS @@ -1508,30 +1323,17 @@ test.serial( }; createOrUpdatePermissionResponse = await request(app.getHttpServer()) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) .send({ permissions }) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - createOrUpdatePermissionRO = JSON.parse( - createOrUpdatePermissionResponse.text, - ); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + createOrUpdatePermissionRO = JSON.parse(createOrUpdatePermissionResponse.text); JSON.stringify(createOrUpdatePermissionRO); t.is(createOrUpdatePermissionResponse.status, 200); - t.is( - JSON.stringify(createOrUpdatePermissionRO.connection), - JSON.stringify(permissions.connection), - ); - t.is( - JSON.stringify(createOrUpdatePermissionRO.group), - JSON.stringify(permissions.group), - ); - t.is( - JSON.stringify(createOrUpdatePermissionRO.tables), - JSON.stringify(permissions.tables), - ); + t.is(JSON.stringify(createOrUpdatePermissionRO.connection), JSON.stringify(permissions.connection)); + t.is(JSON.stringify(createOrUpdatePermissionRO.group), JSON.stringify(permissions.group)); + t.is(JSON.stringify(createOrUpdatePermissionRO.tables), JSON.stringify(permissions.tables)); } catch (error) { console.error(error); throw error; @@ -1539,243 +1341,195 @@ test.serial( }, ); -test.serial( - `${currentTest} should throw an exception, when you try change admin group`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); +test.serial(`${currentTest} should throw an exception, when you try change admin group`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - const permissions = { - connection: { - connectionId: testData.connections.firstId, - accessLevel: AccessLevelEnum.edit, - }, - group: { - groupId: testData.groups.firstAdminGroupId, - accessLevel: AccessLevelEnum.none, + const permissions = { + connection: { + connectionId: testData.connections.firstId, + accessLevel: AccessLevelEnum.edit, + }, + group: { + groupId: testData.groups.firstAdminGroupId, + accessLevel: AccessLevelEnum.none, + }, + tables: [ + { + tableName: testData.firstTableInfo.testTableName, + accessLevel: { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: false, + }, }, - tables: [ - { - tableName: testData.firstTableInfo.testTableName, - accessLevel: { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: false, - }, - }, - ], - }; + ], + }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${testData.groups.firstAdminGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createOrUpdatePermissionRO = JSON.parse( - createOrUpdatePermissionResponse.text, - ); - t.is(createOrUpdatePermissionResponse.status, 400); - t.is( - createOrUpdatePermissionRO.message, - Messages.CANNOT_CHANGE_ADMIN_GROUP, - ); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${testData.groups.firstAdminGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createOrUpdatePermissionRO = JSON.parse(createOrUpdatePermissionResponse.text); + t.is(createOrUpdatePermissionResponse.status, 400); + t.is(createOrUpdatePermissionRO.message, Messages.CANNOT_CHANGE_ADMIN_GROUP); + } catch (error) { + console.error(error); + throw error; + } +}); //****************************** TABLE CONTROLLER -currentTest = "GET /connection/tables/:slug"; +currentTest = 'GET /connection/tables/:slug'; -test.serial( - `${currentTest} should return all tables in connection`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - const newGroup1 = mockFactory.generateCreateGroupDto1(); +test.serial(`${currentTest} should return all tables in connection`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const newGroup1 = mockFactory.generateCreateGroupDto1(); - // create group without visibility table permission - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - const newGroupId = createGroupRO.id; + // create group without visibility table permission + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + const newGroupId = createGroupRO.id; - const permissions = { - connection: { - connectionId: testData.connections.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, - }, - tables: [ - { - tableName: testData.firstTableInfo.testTableName, - accessLevel: { - visibility: false, - readonly: true, - add: false, - delete: false, - edit: false, - }, + const permissions = { + connection: { + connectionId: testData.connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: testData.firstTableInfo.testTableName, + accessLevel: { + visibility: false, + readonly: true, + add: false, + delete: false, + edit: false, }, - ], - }; + }, + ], + }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createOrUpdatePermissionResponse.status, 200); + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createOrUpdatePermissionResponse.status, 200); - const getTablesInConnection = await request(app.getHttpServer()) - .get(`/connection/tables/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesInConnection.status, 200); - const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); - t.is(getTablesInConnectionRO.length > 0, true); - const tableIndex = getTablesInConnectionRO.findIndex( - (tableItem) => - tableItem.table === testData.firstTableInfo.testTableName, - ); - t.is( - getTablesInConnectionRO[tableIndex].table, - testData.firstTableInfo.testTableName, - ); - t.is(typeof getTablesInConnectionRO[tableIndex].permissions, "object"); - const { - visibility, - readonly, - add, - delete: del, - edit, - } = getTablesInConnectionRO[tableIndex].permissions; - t.is(visibility, true); - t.is(readonly, false); - t.is(del, true); - t.is(edit, true); - t.is(add, true); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const getTablesInConnection = await request(app.getHttpServer()) + .get(`/connection/tables/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesInConnection.status, 200); + const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); + t.is(getTablesInConnectionRO.length > 0, true); + const tableIndex = getTablesInConnectionRO.findIndex( + (tableItem) => tableItem.table === testData.firstTableInfo.testTableName, + ); + t.is(getTablesInConnectionRO[tableIndex].table, testData.firstTableInfo.testTableName); + t.is(typeof getTablesInConnectionRO[tableIndex].permissions, 'object'); + const { visibility, readonly, add, delete: del, edit } = getTablesInConnectionRO[tableIndex].permissions; + t.is(visibility, true); + t.is(readonly, false); + t.is(del, true); + t.is(edit, true); + t.is(add, true); + } catch (error) { + console.error(error); + throw error; + } +}); -test.serial( - `${currentTest} should throw an exception, when connection id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); +test.serial(`${currentTest} should throw an exception, when connection id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - const newGroup1 = mockFactory.generateCreateGroupDto1(); + const newGroup1 = mockFactory.generateCreateGroupDto1(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - const newGroupId = createGroupRO.id; + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + const newGroupId = createGroupRO.id; - const permissions = { - connection: { - connectionId: testData.connections.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, - }, - tables: [ - { - tableName: testData.firstTableInfo.testTableName, - accessLevel: { - visibility: false, - readonly: true, - add: false, - delete: false, - edit: false, - }, + const permissions = { + connection: { + connectionId: testData.connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: testData.firstTableInfo.testTableName, + accessLevel: { + visibility: false, + readonly: true, + add: false, + delete: false, + edit: false, }, - ], - }; + }, + ], + }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createOrUpdatePermissionResponse.status, 200); + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createOrUpdatePermissionResponse.status, 200); - const getTablesInConnection = await request(app.getHttpServer()) - .get(`/connection/tables/`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesInConnection.status, 404); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const getTablesInConnection = await request(app.getHttpServer()) + .get(`/connection/tables/`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesInConnection.status, 404); + } catch (error) { + console.error(error); + throw error; + } +}); test.serial( `${currentTest} should throw an exception, when connection id passed in request is incorrect`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const newGroup1 = mockFactory.generateCreateGroupDto1(); // create group without visibility table permission const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) + .set('Cookie', testData.users.simpleUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const createGroupRO = JSON.parse(createGroupResponse.text); const newGroupId = createGroupRO.id; @@ -1790,7 +1544,7 @@ test.serial( }, tables: [ { - tableName: "users", + tableName: 'users', accessLevel: { visibility: false, readonly: true, @@ -1802,24 +1556,20 @@ test.serial( ], }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createOrUpdatePermissionResponse.status, 200); const fakeConnectionId = faker.string.uuid(); const getTablesInConnection = await request(app.getHttpServer()) .get(`/connection/tables/${fakeConnectionId}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getTablesInConnection.status, 400); const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); t.is(getTablesInConnectionRO.message, Messages.CONNECTION_NOT_FOUND); @@ -1830,20 +1580,19 @@ test.serial( }, ); -currentTest = "GET /table/rows/:slug"; +currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return found rows from table`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const newGroup1 = mockFactory.generateCreateGroupDto1(); const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) + .set('Cookie', testData.users.simpleUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const createGroupRO = JSON.parse(createGroupResponse.text); const newGroupId = createGroupRO.id; @@ -1871,36 +1620,25 @@ test.serial(`${currentTest} should return found rows from table`, async (t) => { }; const createOrUpdatePermissionResponse = await request(app.getHttpServer()) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createOrUpdatePermissionResponse.status, 200); const getTablesInConnection = await request(app.getHttpServer()) - .get( - `/table/rows/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`, - ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/table/rows/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getTablesInConnection.status, 200); const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); - const { - rows, - primaryColumns, - pagination, - sortable_by, - structure, - foreignKeys, - } = getTablesInConnectionRO; + const { rows, primaryColumns, pagination, sortable_by, structure, foreignKeys } = getTablesInConnectionRO; t.is(rows.length, Constants.DEFAULT_PAGINATION.perPage); t.is(primaryColumns.length, 1); - t.is(primaryColumns[0].column_name, "id"); - t.is(primaryColumns[0].data_type, "integer"); + t.is(primaryColumns[0].column_name, 'id'); + t.is(primaryColumns[0].data_type, 'integer'); t.is(sortable_by.length, 0); t.is(structure.length, 5); t.is(foreignKeys.length, 0); @@ -1910,234 +1648,199 @@ test.serial(`${currentTest} should return found rows from table`, async (t) => { } }); -test.serial( - `${currentTest} should throw an exception when connection id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - // create group without visibility table permission - const newGroup1 = mockFactory.generateCreateGroupDto1(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - const newGroupId = createGroupRO.id; +test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + // create group without visibility table permission + const newGroup1 = mockFactory.generateCreateGroupDto1(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + const newGroupId = createGroupRO.id; - const permissions = { - connection: { - connectionId: testData.connections.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, + const permissions = { + connection: { + connectionId: testData.connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: testData.firstTableInfo.testTableName, + accessLevel: { + visibility: false, + readonly: true, + add: false, + delete: false, + edit: false, + }, }, - tables: [ - { - tableName: testData.firstTableInfo.testTableName, - accessLevel: { - visibility: false, - readonly: true, - add: false, - delete: false, - edit: false, - }, - }, - ], - }; + ], + }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createOrUpdatePermissionResponse.status, 200); + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createOrUpdatePermissionResponse.status, 200); - const getTablesInConnection = await request(app.getHttpServer()) - .get(`/table/rows/?tableName=${testData.firstTableInfo.testTableName}`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesInConnection.status, 404); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const getTablesInConnection = await request(app.getHttpServer()) + .get(`/table/rows/?tableName=${testData.firstTableInfo.testTableName}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesInConnection.status, 404); + } catch (error) { + console.error(error); + throw error; + } +}); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - // create group without visibility table permission - const newGroup1 = mockFactory.generateCreateGroupDto1(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - const newGroupId = createGroupRO.id; + // create group without visibility table permission + const newGroup1 = mockFactory.generateCreateGroupDto1(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + const newGroupId = createGroupRO.id; - const permissions = { - connection: { - connectionId: testData.connections.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, - }, - tables: [ - { - tableName: testData.firstTableInfo.testTableName, - accessLevel: { - visibility: false, - readonly: true, - add: false, - delete: false, - edit: false, - }, + const permissions = { + connection: { + connectionId: testData.connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: testData.firstTableInfo.testTableName, + accessLevel: { + visibility: false, + readonly: true, + add: false, + delete: false, + edit: false, }, - ], - }; + }, + ], + }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createOrUpdatePermissionResponse.status, 200); + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createOrUpdatePermissionResponse.status, 200); - const fakeId = faker.string.uuid(); - const getTablesInConnection = await request(app.getHttpServer()) - .get( - `/table/rows/${fakeId}?tableName=${testData.firstTableInfo.testTableName}`, - ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesInConnection.status, 403); - const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); - t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const fakeId = faker.string.uuid(); + const getTablesInConnection = await request(app.getHttpServer()) + .get(`/table/rows/${fakeId}?tableName=${testData.firstTableInfo.testTableName}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesInConnection.status, 403); + const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); + t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (error) { + console.error(error); + throw error; + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - // create group without visibility table permission - const newGroup1 = mockFactory.generateCreateGroupDto1(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - const newGroupId = createGroupRO.id; + // create group without visibility table permission + const newGroup1 = mockFactory.generateCreateGroupDto1(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + const newGroupId = createGroupRO.id; - const permissions = { - connection: { - connectionId: testData.connections.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, - }, - tables: [ - { - tableName: testData.firstTableInfo.testTableName, - accessLevel: { - visibility: false, - readonly: true, - add: false, - delete: false, - edit: false, - }, + const permissions = { + connection: { + connectionId: testData.connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: testData.firstTableInfo.testTableName, + accessLevel: { + visibility: false, + readonly: true, + add: false, + delete: false, + edit: false, }, - ], - }; + }, + ], + }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createOrUpdatePermissionResponse.status, 200); + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createOrUpdatePermissionResponse.status, 200); - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTablesInConnection = await request(app.getHttpServer()) - .get( - `/table/rows/${testData.connections.firstId}?tableName=${fakeTableName}`, - ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesInConnection.status, 400); - const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); - t.is(getTablesInConnectionRO.message, Messages.TABLE_NOT_FOUND); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTablesInConnection = await request(app.getHttpServer()) + .get(`/table/rows/${testData.connections.firstId}?tableName=${fakeTableName}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesInConnection.status, 400); + const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); + t.is(getTablesInConnectionRO.message, Messages.TABLE_NOT_FOUND); + } catch (error) { + console.error(error); + throw error; + } +}); -currentTest = "GET /table/structure/:slug"; +currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); // create group without visibility table permission const newGroup1 = mockFactory.generateCreateGroupDto1(); const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) + .set('Cookie', testData.users.simpleUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const createGroupRO = JSON.parse(createGroupResponse.text); const newGroupId = createGroupRO.id; @@ -2165,35 +1868,25 @@ test.serial(`${currentTest} should return table structure`, async (t) => { }; const createOrUpdatePermissionResponse = await request(app.getHttpServer()) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) .send({ permissions }) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createOrUpdatePermissionResponse.status, 200); const getTablesStructure = await request(app.getHttpServer()) - .get( - `/table/structure/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`, - ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/table/structure/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getTablesStructure.status, 200); const getTableStructureRO = JSON.parse(getTablesStructure.text); - const { - structure, - primaryColumns, - foreignKeys, - readonly_fields, - table_widgets, - } = getTableStructureRO; + const { structure, primaryColumns, foreignKeys, readonly_fields, table_widgets } = getTableStructureRO; t.is(structure.length, 5); t.is(primaryColumns.length, 1); - t.is(primaryColumns[0].column_name, "id"); - t.is(primaryColumns[0].data_type, "integer"); + t.is(primaryColumns[0].column_name, 'id'); + t.is(primaryColumns[0].data_type, 'integer'); t.is(readonly_fields.length, 0); t.is(table_widgets.length, 0); t.is(foreignKeys.length, 0); @@ -2203,305 +1896,410 @@ test.serial(`${currentTest} should return table structure`, async (t) => { } }); -test.serial( - `${currentTest} should throw an exception when connection id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); +test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - // create group without visibility table permission - const newGroup1 = mockFactory.generateCreateGroupDto1(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - const newGroupId = createGroupRO.id; + // create group without visibility table permission + const newGroup1 = mockFactory.generateCreateGroupDto1(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + const newGroupId = createGroupRO.id; - const permissions = { - connection: { - connectionId: testData.connections.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, + const permissions = { + connection: { + connectionId: testData.connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: testData.firstTableInfo.testTableName, + accessLevel: { + visibility: false, + readonly: true, + add: false, + delete: false, + edit: false, + }, }, - tables: [ - { - tableName: testData.firstTableInfo.testTableName, - accessLevel: { - visibility: false, - readonly: true, - add: false, - delete: false, - edit: false, - }, - }, - ], - }; + ], + }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createOrUpdatePermissionResponse.status, 200); + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createOrUpdatePermissionResponse.status, 200); - const getTablesStructure = await request(app.getHttpServer()) - .get( - `/table/structure/?tableName=${testData.firstTableInfo.testTableName}`, - ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 404); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/?tableName=${testData.firstTableInfo.testTableName}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 404); + } catch (error) { + console.error(error); + throw error; + } +}); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - // create group without visibility table permission - const newGroup1 = mockFactory.generateCreateGroupDto1(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - const newGroupId = createGroupRO.id; + // create group without visibility table permission + const newGroup1 = mockFactory.generateCreateGroupDto1(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + const newGroupId = createGroupRO.id; - const permissions = { - connection: { - connectionId: testData.connections.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, - }, - tables: [ - { - tableName: testData.firstTableInfo.testTableName, - accessLevel: { - visibility: false, - readonly: true, - add: false, - delete: false, - edit: false, - }, + const permissions = { + connection: { + connectionId: testData.connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: testData.firstTableInfo.testTableName, + accessLevel: { + visibility: false, + readonly: true, + add: false, + delete: false, + edit: false, }, - ], - }; + }, + ], + }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createOrUpdatePermissionResponse.status, 200); + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createOrUpdatePermissionResponse.status, 200); - const fakeConnectionId = faker.string.uuid(); - const getTablesStructure = await request(app.getHttpServer()) - .get(`/table/structure/${fakeConnectionId}?tableName=users`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 403); - const getTablesStructureRO = JSON.parse(getTablesStructure.text); - t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const fakeConnectionId = faker.string.uuid(); + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${fakeConnectionId}?tableName=users`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 403); + const getTablesStructureRO = JSON.parse(getTablesStructure.text); + t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (error) { + console.error(error); + throw error; + } +}); -test.serial( - `${currentTest} should throw an exception when table name not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); +test.serial(`${currentTest} should throw an exception when table name not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - // create group without visibility table permission - const newGroup1 = mockFactory.generateCreateGroupDto1(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - const newGroupId = createGroupRO.id; + // create group without visibility table permission + const newGroup1 = mockFactory.generateCreateGroupDto1(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + const newGroupId = createGroupRO.id; - const permissions = { - connection: { - connectionId: testData.connections.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, - }, - tables: [ - { - tableName: testData.firstTableInfo.testTableName, - accessLevel: { - visibility: false, - readonly: true, - add: false, - delete: false, - edit: false, - }, + const permissions = { + connection: { + connectionId: testData.connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: testData.firstTableInfo.testTableName, + accessLevel: { + visibility: false, + readonly: true, + add: false, + delete: false, + edit: false, }, - ], - }; + }, + ], + }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createOrUpdatePermissionResponse.status, 200); + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createOrUpdatePermissionResponse.status, 200); - const getTablesStructure = await request(app.getHttpServer()) - .get(`/table/structure/${testData.connections.firstId}?tableName=`) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 400); - const getTablesStructureRO = JSON.parse(getTablesStructure.text); - t.is(getTablesStructureRO.message, Messages.TABLE_NAME_MISSING); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${testData.connections.firstId}?tableName=`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 400); + const getTablesStructureRO = JSON.parse(getTablesStructure.text); + t.is(getTablesStructureRO.message, Messages.TABLE_NAME_MISSING); + } catch (error) { + console.error(error); + throw error; + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - // create group without visibility table permission - const newGroup1 = mockFactory.generateCreateGroupDto1(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - const newGroupId = createGroupRO.id; + // create group without visibility table permission + const newGroup1 = mockFactory.generateCreateGroupDto1(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + const newGroupId = createGroupRO.id; - const permissions = { - connection: { - connectionId: testData.connections.firstId, - accessLevel: AccessLevelEnum.readonly, + const permissions = { + connection: { + connectionId: testData.connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: testData.firstTableInfo.testTableName, + accessLevel: { + visibility: false, + readonly: true, + add: false, + delete: false, + edit: false, + }, }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, + ], + }; + + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createOrUpdatePermissionResponse.status, 200); + + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${testData.connections.firstId}?tableName=${fakeTableName}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 400); + const getTablesStructureRO = JSON.parse(getTablesStructure.text); + t.is(getTablesStructureRO.message, Messages.TABLE_NOT_FOUND); + } catch (error) { + console.error(error); + throw error; + } +}); + +currentTest = 'POST /table/row/:slug'; + +test.serial(`${currentTest} should return added row`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + + // create group without visibility table permission + const newGroup1 = mockFactory.generateCreateGroupDto1(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + const newGroupId = createGroupRO.id; + + const permissions = { + connection: { + connectionId: testData.connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: testData.firstTableInfo.testTableName, + accessLevel: { + visibility: false, + readonly: true, + add: false, + delete: false, + edit: false, + }, }, - tables: [ - { - tableName: testData.firstTableInfo.testTableName, - accessLevel: { - visibility: false, - readonly: true, - add: false, - delete: false, - edit: false, - }, + ], + }; + + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createOrUpdatePermissionResponse.status, 200); + + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + + const created_at = new Date(); + const updated_at = new Date(); + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) + .send({ + [testData.firstTableInfo.testTableColumnName]: randomName, + [testData.firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTable.status, 201); + t.is(Object.hasOwn(addRowInTableRO.row, 'id'), true); + t.is(addRowInTableRO.row[testData.firstTableInfo.testTableColumnName], randomName); + t.is(addRowInTableRO.row[testData.firstTableInfo.testTableSecondColumnName], randomEmail); + t.is(Object.hasOwn(addRowInTableRO.row, 'created_at'), true); + t.is(Object.hasOwn(addRowInTableRO.row, 'updated_at'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + } catch (error) { + console.error(error); + throw error; + } +}); + +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + + // create group without visibility table permission + const newGroup1 = mockFactory.generateCreateGroupDto1(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + const newGroupId = createGroupRO.id; + + const permissions = { + connection: { + connectionId: testData.connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: testData.firstTableInfo.testTableName, + accessLevel: { + visibility: false, + readonly: true, + add: false, + delete: false, + edit: false, }, - ], - }; + }, + ], + }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createOrUpdatePermissionResponse.status, 200); + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createOrUpdatePermissionResponse.status, 200); - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTablesStructure = await request(app.getHttpServer()) - .get( - `/table/structure/${testData.connections.firstId}?tableName=${fakeTableName}`, - ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 400); - const getTablesStructureRO = JSON.parse(getTablesStructure.text); - t.is(getTablesStructureRO.message, Messages.TABLE_NOT_FOUND); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); -currentTest = "POST /table/row/:slug"; + const created_at = new Date(); + const updated_at = new Date(); + const fakeConnectionId = faker.string.uuid(); + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${testData.firstTableInfo.testTableName}`) + .send({ + [testData.firstTableInfo.testTableColumnName]: randomName, + [testData.firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (error) { + console.error(error); + throw error; + } +}); -test.serial(`${currentTest} should return added row`, async (t) => { +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); // create group without visibility table permission const newGroup1 = mockFactory.generateCreateGroupDto1(); const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) + .set('Cookie', testData.users.simpleUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const createGroupRO = JSON.parse(createGroupResponse.text); const newGroupId = createGroupRO.id; @@ -2529,13 +2327,11 @@ test.serial(`${currentTest} should return added row`, async (t) => { }; const createOrUpdatePermissionResponse = await request(app.getHttpServer()) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createOrUpdatePermissionResponse.status, 200); const randomName = faker.person.firstName(); @@ -2543,223 +2339,191 @@ test.serial(`${currentTest} should return added row`, async (t) => { const created_at = new Date(); const updated_at = new Date(); + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`, - ) + .post(`/table/row/${testData.connections.firstId}?tableName=${fakeTableName}`) .send({ [testData.firstTableInfo.testTableColumnName]: randomName, [testData.firstTableInfo.testTableSecondColumnName]: randomEmail, created_at: created_at, updated_at: updated_at, }) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTable.status, 201); - t.is(Object.hasOwn(addRowInTableRO.row, "id"), true); - t.is( - addRowInTableRO.row[testData.firstTableInfo.testTableColumnName], - randomName, - ); - t.is( - addRowInTableRO.row[testData.firstTableInfo.testTableSecondColumnName], - randomEmail, - ); - t.is(Object.hasOwn(addRowInTableRO.row, "created_at"), true); - t.is(Object.hasOwn(addRowInTableRO.row, "updated_at"), true); - t.is(Object.hasOwn(addRowInTableRO, "structure"), true); - t.is(Object.hasOwn(addRowInTableRO, "foreignKeys"), true); - t.is(Object.hasOwn(addRowInTableRO, "primaryColumns"), true); - t.is(Object.hasOwn(addRowInTableRO, "readonly_fields"), true); + t.is(addRowInTableRO.message, Messages.TABLE_NOT_FOUND); } catch (error) { console.error(error); throw error; } }); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); +currentTest = 'PUT /table/row/:slug'; - // create group without visibility table permission - const newGroup1 = mockFactory.generateCreateGroupDto1(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - const newGroupId = createGroupRO.id; +test.serial(`${currentTest} should return updated row`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - const permissions = { - connection: { - connectionId: testData.connections.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, - }, - tables: [ - { - tableName: testData.firstTableInfo.testTableName, - accessLevel: { - visibility: false, - readonly: true, - add: false, - delete: false, - edit: false, - }, + // create group without visibility table permission + const newGroup1 = mockFactory.generateCreateGroupDto1(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + const newGroupId = createGroupRO.id; + + const permissions = { + connection: { + connectionId: testData.connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: testData.firstTableInfo.testTableName, + accessLevel: { + visibility: false, + readonly: true, + add: false, + delete: false, + edit: false, }, - ], - }; + }, + ], + }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createOrUpdatePermissionResponse.status, 200); + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); + t.is(createOrUpdatePermissionResponse.status, 200); - const created_at = new Date(); - const updated_at = new Date(); - const fakeConnectionId = faker.string.uuid(); - const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${fakeConnectionId}?tableName=${testData.firstTableInfo.testTableName}`, - ) - .send({ - [testData.firstTableInfo.testTableColumnName]: randomName, - [testData.firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); + const created_at = new Date(); + const updated_at = new Date(); + const updateRowInTable = await request(app.getHttpServer()) + .put(`/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}&id=2`) + .send({ + [testData.firstTableInfo.testTableColumnName]: randomName, + [testData.firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(updateRowInTable.text); + t.is(updateRowInTable.status, 200); + t.is(Object.hasOwn(addRowInTableRO.row, 'id'), true); + t.is(addRowInTableRO.row[testData.firstTableInfo.testTableColumnName], randomName); + t.is(addRowInTableRO.row[testData.firstTableInfo.testTableSecondColumnName], randomEmail); + t.is(Object.hasOwn(addRowInTableRO.row, 'created_at'), true); + t.is(Object.hasOwn(addRowInTableRO.row, 'updated_at'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); + } catch (error) { + console.error(error); + throw error; + } +}); - // create group without visibility table permission - const newGroup1 = mockFactory.generateCreateGroupDto1(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - const newGroupId = createGroupRO.id; +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - const permissions = { - connection: { - connectionId: testData.connections.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, - }, - tables: [ - { - tableName: testData.firstTableInfo.testTableName, - accessLevel: { - visibility: false, - readonly: true, - add: false, - delete: false, - edit: false, - }, - }, - ], - }; + // create group without visibility table permission + const newGroup1 = mockFactory.generateCreateGroupDto1(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + const newGroupId = createGroupRO.id; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createOrUpdatePermissionResponse.status, 200); + const permissions = { + connection: { + connectionId: testData.connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: testData.firstTableInfo.testTableName, + accessLevel: { + visibility: false, + readonly: true, + add: false, + delete: false, + edit: false, + }, + }, + ], + }; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createOrUpdatePermissionResponse.status, 200); - const created_at = new Date(); - const updated_at = new Date(); - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${testData.connections.firstId}?tableName=${fakeTableName}`, - ) - .send({ - [testData.firstTableInfo.testTableColumnName]: randomName, - [testData.firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.TABLE_NOT_FOUND); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); -currentTest = "PUT /table/row/:slug"; + const created_at = new Date(); + const updated_at = new Date(); + const fakeConnectionId = faker.string.uuid(); + const addRowInTable = await request(app.getHttpServer()) + .put(`/table/row/${fakeConnectionId}?tableName=${testData.firstTableInfo.testTableName}&id=1`) + .send({ + [testData.firstTableInfo.testTableColumnName]: randomName, + [testData.firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (error) { + console.error(error); + throw error; + } +}); -test.serial(`${currentTest} should return updated row`, async (t) => { +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); // create group without visibility table permission const newGroup1 = mockFactory.generateCreateGroupDto1(); const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) + .set('Cookie', testData.users.simpleUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const createGroupRO = JSON.parse(createGroupResponse.text); const newGroupId = createGroupRO.id; @@ -2787,14 +2551,11 @@ test.serial(`${currentTest} should return updated row`, async (t) => { }; const createOrUpdatePermissionResponse = await request(app.getHttpServer()) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createOrUpdatePermissionResponse.status, 200); const randomName = faker.person.firstName(); @@ -2802,223 +2563,40 @@ test.serial(`${currentTest} should return updated row`, async (t) => { const created_at = new Date(); const updated_at = new Date(); - const updateRowInTable = await request(app.getHttpServer()) - .put( - `/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}&id=2`, - ) + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTable = await request(app.getHttpServer()) + .put(`/table/row/${testData.connections.firstId}?tableName=${fakeTableName}&id=1`) .send({ [testData.firstTableInfo.testTableColumnName]: randomName, [testData.firstTableInfo.testTableSecondColumnName]: randomEmail, created_at: created_at, updated_at: updated_at, }) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(updateRowInTable.text); - t.is(updateRowInTable.status, 200); - t.is(Object.hasOwn(addRowInTableRO.row, "id"), true); - t.is( - addRowInTableRO.row[testData.firstTableInfo.testTableColumnName], - randomName, - ); - t.is( - addRowInTableRO.row[testData.firstTableInfo.testTableSecondColumnName], - randomEmail, - ); - t.is(Object.hasOwn(addRowInTableRO.row, "created_at"), true); - t.is(Object.hasOwn(addRowInTableRO.row, "updated_at"), true); - t.is(Object.hasOwn(addRowInTableRO, "structure"), true); - t.is(Object.hasOwn(addRowInTableRO, "foreignKeys"), true); - t.is(Object.hasOwn(addRowInTableRO, "primaryColumns"), true); - t.is(Object.hasOwn(addRowInTableRO, "readonly_fields"), true); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.TABLE_NOT_FOUND); } catch (error) { console.error(error); throw error; } }); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - - // create group without visibility table permission - const newGroup1 = mockFactory.generateCreateGroupDto1(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - const newGroupId = createGroupRO.id; - - const permissions = { - connection: { - connectionId: testData.connections.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, - }, - tables: [ - { - tableName: testData.firstTableInfo.testTableName, - accessLevel: { - visibility: false, - readonly: true, - add: false, - delete: false, - edit: false, - }, - }, - ], - }; - - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createOrUpdatePermissionResponse.status, 200); - - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - - const created_at = new Date(); - const updated_at = new Date(); - const fakeConnectionId = faker.string.uuid(); - const addRowInTable = await request(app.getHttpServer()) - .put( - `/table/row/${fakeConnectionId}?tableName=${testData.firstTableInfo.testTableName}&id=1`, - ) - .send({ - [testData.firstTableInfo.testTableColumnName]: randomName, - [testData.firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (error) { - console.error(error); - throw error; - } - }, -); - -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - - // create group without visibility table permission - const newGroup1 = mockFactory.generateCreateGroupDto1(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - const newGroupId = createGroupRO.id; - - const permissions = { - connection: { - connectionId: testData.connections.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, - }, - tables: [ - { - tableName: testData.firstTableInfo.testTableName, - accessLevel: { - visibility: false, - readonly: true, - add: false, - delete: false, - edit: false, - }, - }, - ], - }; - - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createOrUpdatePermissionResponse.status, 200); - - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - - const created_at = new Date(); - const updated_at = new Date(); - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTable = await request(app.getHttpServer()) - .put( - `/table/row/${testData.connections.firstId}?tableName=${fakeTableName}&id=1`, - ) - .send({ - [testData.firstTableInfo.testTableColumnName]: randomName, - [testData.firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.TABLE_NOT_FOUND); - } catch (error) { - console.error(error); - throw error; - } - }, -); - -currentTest = "DELETE /table/row/:slug"; +currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should return delete result`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const newGroup1 = mockFactory.generateCreateGroupDto1(); // create group without visibility table permission const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) + .set('Cookie', testData.users.simpleUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const createGroupRO = JSON.parse(createGroupResponse.text); const newGroupId = createGroupRO.id; @@ -3046,22 +2624,18 @@ test.serial(`${currentTest} should return delete result`, async (t) => { }; const createOrUpdatePermissionResponse = await request(app.getHttpServer()) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createOrUpdatePermissionResponse.status, 200); const deleteRowInTable = await request(app.getHttpServer()) - .delete( - `/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}&id=1`, - ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .delete(`/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}&id=1`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(deleteRowInTable.status, 200); } catch (error) { console.error(error); @@ -3069,165 +2643,140 @@ test.serial(`${currentTest} should return delete result`, async (t) => { } }); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - // create group without visibility table permission - const newGroup1 = mockFactory.generateCreateGroupDto1(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - const newGroupId = createGroupRO.id; + // create group without visibility table permission + const newGroup1 = mockFactory.generateCreateGroupDto1(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + const newGroupId = createGroupRO.id; - const permissions = { - connection: { - connectionId: testData.connections.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, - }, - tables: [ - { - tableName: testData.firstTableInfo.testTableName, - accessLevel: { - visibility: false, - readonly: true, - add: false, - delete: false, - edit: false, - }, + const permissions = { + connection: { + connectionId: testData.connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: testData.firstTableInfo.testTableName, + accessLevel: { + visibility: false, + readonly: true, + add: false, + delete: false, + edit: false, }, - ], - }; + }, + ], + }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createOrUpdatePermissionResponse.status, 200); + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createOrUpdatePermissionResponse.status, 200); - const fakeConnectionId = faker.string.uuid(); - const deleteRowInTable = await request(app.getHttpServer()) - .delete( - `/table/row/${fakeConnectionId}?tableName=${testData.firstTableInfo.testTableName}&id=1`, - ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteRowInTableRO = JSON.parse(deleteRowInTable.text); - t.is(deleteRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - t.is(deleteRowInTable.status, 403); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const fakeConnectionId = faker.string.uuid(); + const deleteRowInTable = await request(app.getHttpServer()) + .delete(`/table/row/${fakeConnectionId}?tableName=${testData.firstTableInfo.testTableName}&id=1`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteRowInTableRO = JSON.parse(deleteRowInTable.text); + t.is(deleteRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + t.is(deleteRowInTable.status, 403); + } catch (error) { + console.error(error); + throw error; + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - const newGroup1 = mockFactory.generateCreateGroupDto1(); + const newGroup1 = mockFactory.generateCreateGroupDto1(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - const newGroupId = createGroupRO.id; + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + const newGroupId = createGroupRO.id; - const permissions = { - connection: { - connectionId: testData.connections.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, - }, - tables: [ - { - tableName: testData.firstTableInfo.testTableName, - accessLevel: { - visibility: false, - readonly: true, - add: false, - delete: false, - edit: false, - }, + const permissions = { + connection: { + connectionId: testData.connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: testData.firstTableInfo.testTableName, + accessLevel: { + visibility: false, + readonly: true, + add: false, + delete: false, + edit: false, }, - ], - }; + }, + ], + }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createOrUpdatePermissionResponse.status, 200); - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTable = await request(app.getHttpServer()) - .delete( - `/table/row/${testData.connections.firstId}?tableName=${fakeTableName}&id=1`, - ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteRowInTabbleRO = JSON.parse(deleteRowInTable.text); - t.is(deleteRowInTabbleRO.message, Messages.TABLE_NOT_FOUND); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createOrUpdatePermissionResponse.status, 200); + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTable = await request(app.getHttpServer()) + .delete(`/table/row/${testData.connections.firstId}?tableName=${fakeTableName}&id=1`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteRowInTabbleRO = JSON.parse(deleteRowInTable.text); + t.is(deleteRowInTabbleRO.message, Messages.TABLE_NOT_FOUND); + } catch (error) { + console.error(error); + throw error; + } +}); -currentTest = "GET /table/row/:slug"; +currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} `, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const newGroup1 = mockFactory.generateCreateGroupDto1(); // create group without visibility table permission const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) + .set('Cookie', testData.users.simpleUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const createGroupRO = JSON.parse(createGroupResponse.text); const newGroupId = createGroupRO.id; @@ -3255,251 +2804,209 @@ test.serial(`${currentTest} `, async (t) => { }; const createOrUpdatePermissionResponse = await request(app.getHttpServer()) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createOrUpdatePermissionResponse.status, 200); const getRowInTable = await request(app.getHttpServer()) - .get( - `/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}&id=5`, - ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}&id=5`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getRowInTableRO = JSON.parse(getRowInTable.text); t.is(getRowInTable.status, 200); t.is(getRowInTableRO.row.id, 5); - t.is(Object.hasOwn(getRowInTableRO.row, "created_at"), true); - t.is(Object.hasOwn(getRowInTableRO.row, "updated_at"), true); - t.is(Object.hasOwn(getRowInTableRO, "structure"), true); - t.is(Object.hasOwn(getRowInTableRO, "foreignKeys"), true); - t.is(Object.hasOwn(getRowInTableRO, "primaryColumns"), true); - t.is(Object.hasOwn(getRowInTableRO, "readonly_fields"), true); + t.is(Object.hasOwn(getRowInTableRO.row, 'created_at'), true); + t.is(Object.hasOwn(getRowInTableRO.row, 'updated_at'), true); + t.is(Object.hasOwn(getRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(getRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(getRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getRowInTableRO, 'readonly_fields'), true); } catch (error) { console.error(error); throw error; } }); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - // create group without visibility table permission - const newGroup1 = mockFactory.generateCreateGroupDto1(); + // create group without visibility table permission + const newGroup1 = mockFactory.generateCreateGroupDto1(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - const newGroupId = createGroupRO.id; + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + const newGroupId = createGroupRO.id; - const permissions = { - connection: { - connectionId: testData.connections.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, - }, - tables: [ - { - tableName: testData.firstTableInfo.testTableName, - accessLevel: { - visibility: false, - readonly: true, - add: false, - delete: false, - edit: false, - }, + const permissions = { + connection: { + connectionId: testData.connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: testData.firstTableInfo.testTableName, + accessLevel: { + visibility: false, + readonly: true, + add: false, + delete: false, + edit: false, }, - ], - }; + }, + ], + }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createOrUpdatePermissionResponse.status, 200); + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createOrUpdatePermissionResponse.status, 200); - const fakeConnectionId = faker.string.uuid(); - const addRowInTable = await request(app.getHttpServer()) - .get( - `/table/row/${fakeConnectionId}?tableName=${testData.firstTableInfo.testTableName}&id=5`, - ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const fakeConnectionId = faker.string.uuid(); + const addRowInTable = await request(app.getHttpServer()) + .get(`/table/row/${fakeConnectionId}?tableName=${testData.firstTableInfo.testTableName}&id=5`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (error) { + console.error(error); + throw error; + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - // create group without visibility table permission - const newGroup1 = mockFactory.generateCreateGroupDto1(); + // create group without visibility table permission + const newGroup1 = mockFactory.generateCreateGroupDto1(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${testData.connections.firstId}`) - .set("Cookie", testData.users.simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - const newGroupId = createGroupRO.id; + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${testData.connections.firstId}`) + .set('Cookie', testData.users.simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + const newGroupId = createGroupRO.id; - const permissions = { - connection: { - connectionId: testData.connections.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, - }, - tables: [ - { - tableName: testData.firstTableInfo.testTableName, - accessLevel: { - visibility: false, - readonly: true, - add: false, - delete: false, - edit: false, - }, + const permissions = { + connection: { + connectionId: testData.connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: testData.firstTableInfo.testTableName, + accessLevel: { + visibility: false, + readonly: true, + add: false, + delete: false, + edit: false, }, - ], - }; + }, + ], + }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createOrUpdatePermissionResponse.status, 200); + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createOrUpdatePermissionResponse.status, 200); - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTable = await request(app.getHttpServer()) - .get( - `/table/row/${testData.connections.firstId}?tableName=${fakeTableName}&id=5`, - ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.TABLE_NOT_FOUND); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTable = await request(app.getHttpServer()) + .get(`/table/row/${testData.connections.firstId}?tableName=${fakeTableName}&id=5`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.TABLE_NOT_FOUND); + } catch (error) { + console.error(error); + throw error; + } +}); //****************************** TABLE LOGS CONTROLLER -currentTest = "GET /logs/:slug"; - -test.serial( - `${currentTest} should return all found logs in connection`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); +currentTest = 'GET /logs/:slug'; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - /* eslint-disable */ - const created_at = new Date(); - const updated_at = new Date(); - const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`, - ) - .send({ - [testData.firstTableInfo.testTableColumnName]: randomName, - [testData.firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(addRowInTable.status, 201); +test.serial(`${currentTest} should return all found logs in connection`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - const getTableLogs = await request(app.getHttpServer()) - .get(`/logs/${testData.connections.firstId}`) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getRowInTableRO = JSON.parse(getTableLogs.text); + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + /* eslint-disable */ + const created_at = new Date(); + const updated_at = new Date(); + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) + .send({ + [testData.firstTableInfo.testTableColumnName]: randomName, + [testData.firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTable.status, 201); - t.is(getRowInTableRO.logs.length, 1); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "table_name"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "received_data"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "old_data"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "cognitoUserName"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "email"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "operationType"), true); - t.is( - Object.hasOwn(getRowInTableRO.logs[0], "operationStatusResult"), - true, - ); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "createdAt"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "connection_id"), true); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const getTableLogs = await request(app.getHttpServer()) + .get(`/logs/${testData.connections.firstId}`) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getRowInTableRO = JSON.parse(getTableLogs.text); + + t.is(getRowInTableRO.logs.length, 1); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'table_name'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'received_data'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'old_data'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'cognitoUserName'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'email'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'operationType'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'operationStatusResult'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'createdAt'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'connection_id'), true); + } catch (error) { + console.error(error); + throw error; + } +}); test.serial( `${currentTest} should not return all found logs in connection, when table audit is disabled in connection'`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); const { connections, firstTableInfo, @@ -3513,52 +3020,46 @@ test.serial( const created_at = new Date(); const updated_at = new Date(); - const updateConnection = - mockFactory.generateConnectionToTestPostgresDBInDocker(); + const updateConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); const updateConnectionResponse = await request(app.getHttpServer()) .put(`/connection/${connections.firstId}`) .send(updateConnection) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(updateConnectionResponse.status, 200); - const newConnectionProperties = - mockFactory.generateConnectionPropertiesUserExcluded(null, false); + const newConnectionProperties = mockFactory.generateConnectionPropertiesUserExcluded(null, false); - const createConnectionPropertiesResponse = await request( - app.getHttpServer(), - ) + const createConnectionPropertiesResponse = await request(app.getHttpServer()) .post(`/connection/properties/${connections.firstId}`) .send(newConnectionProperties) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createConnectionPropertiesResponse.status, 201); const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) + .post(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) .send({ [firstTableInfo.testTableColumnName]: randomName, [firstTableInfo.testTableSecondColumnName]: randomEmail, created_at: created_at, updated_at: updated_at, }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(addRowInTable.status, 201); const getTableLogs = await request(app.getHttpServer()) .get(`/logs/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getRowInTableRO = JSON.parse(getTableLogs.text); t.is(getRowInTableRO.logs.length, 0); @@ -3571,127 +3072,109 @@ test.serial( //****************************** TABLE SETTINGS CONTROLLER -currentTest = "GET /settings/"; - -test.serial( - `${currentTest} should return empty table settings when it was not created`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - - const getTableSettings = await request(app.getHttpServer()) - .get( - `/settings/?connectionId=${testData.connections.firstId}&tableName=users`, - ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getTableSettingsRO = JSON.parse(getTableSettings.text); - t.is(getTableSettings.status, 200); - t.is(JSON.stringify(getTableSettingsRO), JSON.stringify({})); - } catch (error) { - console.error(error); - throw error; - } - }, -); - -test.serial( - `${currentTest} should return table settings when it was created`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - testData.connections.firstId, - testData.firstTableInfo.testTableName, - ['id'], - [testData.firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); +currentTest = 'GET /settings/'; - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${testData.connections.firstId}&tableName=${testData.firstTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should return empty table settings when it was not created`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + + const getTableSettings = await request(app.getHttpServer()) + .get(`/settings/?connectionId=${testData.connections.firstId}&tableName=users`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getTableSettingsRO = JSON.parse(getTableSettings.text); + t.is(getTableSettings.status, 200); + t.is(JSON.stringify(getTableSettingsRO), JSON.stringify({})); + } catch (error) { + console.error(error); + throw error; + } +}); - t.is(createTableSettingsResponse.status, 201); +test.serial(`${currentTest} should return table settings when it was created`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + testData.connections.firstId, + testData.firstTableInfo.testTableName, + ['id'], + [testData.firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); - const getTableSettings = await request(app.getHttpServer()) - .get(`/settings/?connectionId=${testData.connections.firstId}&tableName=${testData.firstTableInfo.testTableName}`) - .set('Cookie', testData.users.simpleUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const getTableSettingsRO = JSON.parse(getTableSettings.text); - t.is(getTableSettings.status, 200); - t.is(getTableSettingsRO.hasOwnProperty('id'), true); - t.is(getTableSettingsRO.table_name, createTableSettingsDTO.table_name); - t.is(getTableSettingsRO.display_name, createTableSettingsDTO.display_name); - t.is(JSON.stringify(getTableSettingsRO.search_fields), JSON.stringify(createTableSettingsDTO.search_fields)); - t.is(JSON.stringify(getTableSettingsRO.excluded_fields), JSON.stringify(createTableSettingsDTO.excluded_fields)); - t.is(JSON.stringify(getTableSettingsRO.identification_fields), JSON.stringify([])); - t.is(JSON.stringify(getTableSettingsRO.readonly_fields), JSON.stringify(createTableSettingsDTO.readonly_fields)); - t.is(JSON.stringify(getTableSettingsRO.sortable_by), JSON.stringify(createTableSettingsDTO.sortable_by)); - t.is(JSON.stringify(getTableSettingsRO.autocomplete_columns), JSON.stringify([])); - t.is(getTableSettingsRO.connection_id, testData.connections.firstId); - } catch (error) { - console.error(error); - throw error; - } + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${testData.connections.firstId}&tableName=${testData.firstTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const getTableSettings = await request(app.getHttpServer()) + .get(`/settings/?connectionId=${testData.connections.firstId}&tableName=${testData.firstTableInfo.testTableName}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getTableSettingsRO = JSON.parse(getTableSettings.text); + t.is(getTableSettings.status, 200); + t.is(getTableSettingsRO.hasOwnProperty('id'), true); + t.is(getTableSettingsRO.table_name, createTableSettingsDTO.table_name); + t.is(getTableSettingsRO.display_name, createTableSettingsDTO.display_name); + t.is(JSON.stringify(getTableSettingsRO.search_fields), JSON.stringify(createTableSettingsDTO.search_fields)); + t.is(JSON.stringify(getTableSettingsRO.excluded_fields), JSON.stringify(createTableSettingsDTO.excluded_fields)); + t.is(JSON.stringify(getTableSettingsRO.identification_fields), JSON.stringify([])); + t.is(JSON.stringify(getTableSettingsRO.readonly_fields), JSON.stringify(createTableSettingsDTO.readonly_fields)); + t.is(JSON.stringify(getTableSettingsRO.sortable_by), JSON.stringify(createTableSettingsDTO.sortable_by)); + t.is(JSON.stringify(getTableSettingsRO.autocomplete_columns), JSON.stringify([])); + t.is(getTableSettingsRO.connection_id, testData.connections.firstId); + } catch (error) { + console.error(error); + throw error; + } }); test.serial( `${currentTest} should throw an exception when you try get settings in connection where you do not have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - testData.connections.firstId, - testData.firstTableInfo.testTableName, - ['id'], - [testData.firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + testData.connections.firstId, + testData.firstTableInfo.testTableName, + ['id'], + [testData.firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); const createTableSettingsResponse = await request(app.getHttpServer()) .post( `/settings?connectionId=${testData.connections.firstId}&tableName=${testData.firstTableInfo.testTableName}`, ) .send(createTableSettingsDTO) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createTableSettingsResponse.status, 201); const getTableSettings = await request(app.getHttpServer()) .get( `/settings/?connectionId=${testData.connections.secondId}&tableName=${testData.firstTableInfo.testTableName}`, ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getTableSettingsRO = JSON.parse(getTableSettings.text); t.is(getTableSettings.status, 403); t.is(getTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); @@ -3702,90 +3185,78 @@ test.serial( }, ); -currentTest = "POST /settings/"; - -test.serial( - `${currentTest} should return created table settings`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - testData.connections.firstId, - testData.firstTableInfo.testTableName, - ['id'], - [testData.firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); +currentTest = 'POST /settings/'; - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${testData.connections.firstId}&tableName=${testData.firstTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); +test.serial(`${currentTest} should return created table settings`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + testData.connections.firstId, + testData.firstTableInfo.testTableName, + ['id'], + [testData.firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); - const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); - t.is(createTableSettingsRO.hasOwnProperty('id'), true); - t.is(createTableSettingsRO.table_name, createTableSettingsDTO.table_name); - t.is(createTableSettingsRO.display_name, createTableSettingsDTO.display_name); - t.is(JSON.stringify(createTableSettingsRO.search_fields), JSON.stringify(createTableSettingsDTO.search_fields)); - t.is(JSON.stringify(createTableSettingsRO.excluded_fields), JSON.stringify(createTableSettingsDTO.excluded_fields)); - t.is(JSON.stringify(createTableSettingsRO.identification_fields), JSON.stringify([])); - t.is(JSON.stringify(createTableSettingsRO.readonly_fields), JSON.stringify(createTableSettingsDTO.readonly_fields)); - t.is(JSON.stringify(createTableSettingsRO.sortable_by), JSON.stringify(createTableSettingsDTO.sortable_by)); - t.is(JSON.stringify(createTableSettingsRO.autocomplete_columns), JSON.stringify([])); - t.is(createTableSettingsRO.connection_id, testData.connections.firstId); - } catch (error) { - console.error(error); - throw error; - } + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${testData.connections.firstId}&tableName=${testData.firstTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); + t.is(createTableSettingsRO.hasOwnProperty('id'), true); + t.is(createTableSettingsRO.table_name, createTableSettingsDTO.table_name); + t.is(createTableSettingsRO.display_name, createTableSettingsDTO.display_name); + t.is(JSON.stringify(createTableSettingsRO.search_fields), JSON.stringify(createTableSettingsDTO.search_fields)); + t.is(JSON.stringify(createTableSettingsRO.excluded_fields), JSON.stringify(createTableSettingsDTO.excluded_fields)); + t.is(JSON.stringify(createTableSettingsRO.identification_fields), JSON.stringify([])); + t.is(JSON.stringify(createTableSettingsRO.readonly_fields), JSON.stringify(createTableSettingsDTO.readonly_fields)); + t.is(JSON.stringify(createTableSettingsRO.sortable_by), JSON.stringify(createTableSettingsDTO.sortable_by)); + t.is(JSON.stringify(createTableSettingsRO.autocomplete_columns), JSON.stringify([])); + t.is(createTableSettingsRO.connection_id, testData.connections.firstId); + } catch (error) { + console.error(error); + throw error; + } }); test.serial( `${currentTest} should throw an exception when you try create settings in connection where you do not have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - testData.connections.firstId, - testData.firstTableInfo.testTableName, - ['id'], - [testData.firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + testData.connections.firstId, + testData.firstTableInfo.testTableName, + ['id'], + [testData.firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); const createTableSettingsResponse = await request(app.getHttpServer()) .post( `/settings?connectionId=${testData.connections.secondId}&tableName=${testData.firstTableInfo.testTableName}`, ) .send(createTableSettingsDTO) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createTableSettingsResponse.status, 403); - const createTableSettingsRO = JSON.parse( - createTableSettingsResponse.text, - ); + const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); t.is(createTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (error) { console.error(error); @@ -3794,136 +3265,119 @@ test.serial( }, ); -currentTest = "PUT /settings/"; - -test.serial( - `${currentTest} should return updated table settings`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - testData.connections.firstId, - testData.firstTableInfo.testTableName, - ['id'], - [testData.firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); +currentTest = 'PUT /settings/'; - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${testData.connections.firstId}&tableName=${testData.firstTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); +test.serial(`${currentTest} should return updated table settings`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + testData.connections.firstId, + testData.firstTableInfo.testTableName, + ['id'], + [testData.firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); - const updateTableSettingsDTO = mockFactory.generateTableSettings( - testData.connections.firstId, - testData.firstTableInfo.testTableName, - ['id'], - [testData.firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${testData.connections.firstId}&tableName=${testData.firstTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const updateTableSettingsDTO = mockFactory.generateTableSettings( + testData.connections.firstId, + testData.firstTableInfo.testTableName, + ['id'], + [testData.firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); - const updateTableSettingsResponse = await request(app.getHttpServer()) - .put( - `/settings?connectionId=${testData.connections.firstId}&tableName=${testData.firstTableInfo.testTableName}`, - ) - .send(updateTableSettingsDTO) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const updateTableSettingsRO = JSON.parse( - updateTableSettingsResponse.text, - ); - t.is(updateTableSettingsResponse.status, 200); - - t.is(updateTableSettingsRO.hasOwnProperty('id'), true); - t.is(updateTableSettingsRO.table_name, updateTableSettingsDTO.table_name); - t.is(updateTableSettingsRO.display_name, updateTableSettingsDTO.display_name); - t.is(JSON.stringify(updateTableSettingsRO.search_fields), JSON.stringify(updateTableSettingsDTO.search_fields)); - t.is(JSON.stringify(updateTableSettingsRO.excluded_fields), JSON.stringify(updateTableSettingsDTO.excluded_fields)); - t.is(JSON.stringify(updateTableSettingsRO.readonly_fields), JSON.stringify(updateTableSettingsDTO.readonly_fields)); - t.is(JSON.stringify(updateTableSettingsRO.sortable_by), JSON.stringify(updateTableSettingsDTO.sortable_by)); - // t.is(JSON.stringify(updateTableSettingsRO.autocomplete_columns)).toBe(JSON.stringify([])); - t.is(updateTableSettingsRO.connection_id, testData.connections.firstId); - } catch (error) { - console.error(error); - throw error; - } + const updateTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings?connectionId=${testData.connections.firstId}&tableName=${testData.firstTableInfo.testTableName}`) + .send(updateTableSettingsDTO) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const updateTableSettingsRO = JSON.parse(updateTableSettingsResponse.text); + t.is(updateTableSettingsResponse.status, 200); + + t.is(updateTableSettingsRO.hasOwnProperty('id'), true); + t.is(updateTableSettingsRO.table_name, updateTableSettingsDTO.table_name); + t.is(updateTableSettingsRO.display_name, updateTableSettingsDTO.display_name); + t.is(JSON.stringify(updateTableSettingsRO.search_fields), JSON.stringify(updateTableSettingsDTO.search_fields)); + t.is(JSON.stringify(updateTableSettingsRO.excluded_fields), JSON.stringify(updateTableSettingsDTO.excluded_fields)); + t.is(JSON.stringify(updateTableSettingsRO.readonly_fields), JSON.stringify(updateTableSettingsDTO.readonly_fields)); + t.is(JSON.stringify(updateTableSettingsRO.sortable_by), JSON.stringify(updateTableSettingsDTO.sortable_by)); + // t.is(JSON.stringify(updateTableSettingsRO.autocomplete_columns)).toBe(JSON.stringify([])); + t.is(updateTableSettingsRO.connection_id, testData.connections.firstId); + } catch (error) { + console.error(error); + throw error; + } }); test.serial( `${currentTest} should throw an exception when you try update settings in connection where you do not have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - testData.connections.secondId, - testData.secondTableInfo.testTableName, - ['id'], - [testData.secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + testData.connections.secondId, + testData.secondTableInfo.testTableName, + ['id'], + [testData.secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); const createTableSettingsResponse = await request(app.getHttpServer()) .post( `/settings?connectionId=${testData.connections.secondId}&tableName=${testData.secondTableInfo.testTableName}`, ) .send(createTableSettingsDTO) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createTableSettingsResponse.status, 201); - const updateTableSettingsDTO = mockFactory.generateTableSettings( - testData.connections.firstId, - testData.secondTableInfo.testTableName, - ['id'], - [testData.secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const updateTableSettingsDTO = mockFactory.generateTableSettings( + testData.connections.firstId, + testData.secondTableInfo.testTableName, + ['id'], + [testData.secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); const updateTableSettingsResponse = await request(app.getHttpServer()) .put( `/settings?connectionId=${testData.connections.secondId}&tableName=${testData.secondTableInfo.testTableName}`, ) .send(updateTableSettingsDTO) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(updateTableSettingsResponse.status, 403); - t.is( - JSON.parse(updateTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + t.is(JSON.parse(updateTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); } catch (error) { console.error(error); throw error; @@ -3931,95 +3385,82 @@ test.serial( }, ); -currentTest = "DELETE /settings/"; - -test.serial( - `${currentTest} should return array without deleted table settings`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - testData.connections.firstId, - testData.firstTableInfo.testTableName, - ['id'], - [testData.firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${testData.connections.firstId}&tableName=${testData.firstTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); +currentTest = 'DELETE /settings/'; - const deleteTableSettingsResponse = await request(app.getHttpServer()) - .delete( - `/settings/?connectionId=${testData.connections.firstId}&tableName=${testData.firstTableInfo.testTableName}`, - ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should return array without deleted table settings`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + testData.connections.firstId, + testData.firstTableInfo.testTableName, + ['id'], + [testData.firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); - t.is(deleteTableSettingsResponse.status, 200); + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${testData.connections.firstId}&tableName=${testData.firstTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); - const getTableSettings = await request(app.getHttpServer()) - .get( - `/settings/?connectionId=${testData.connections.firstId}&tableName=${testData.firstTableInfo.testTableName}`, - ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getTableSettingsRO = JSON.parse(getTableSettings.text); - t.is(getTableSettings.status, 200); - t.is(JSON.stringify(getTableSettingsRO), JSON.stringify({})); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const deleteTableSettingsResponse = await request(app.getHttpServer()) + .delete( + `/settings/?connectionId=${testData.connections.firstId}&tableName=${testData.firstTableInfo.testTableName}`, + ) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteTableSettingsResponse.status, 200); + + const getTableSettings = await request(app.getHttpServer()) + .get(`/settings/?connectionId=${testData.connections.firstId}&tableName=${testData.firstTableInfo.testTableName}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getTableSettingsRO = JSON.parse(getTableSettings.text); + t.is(getTableSettings.status, 200); + t.is(JSON.stringify(getTableSettingsRO), JSON.stringify({})); + } catch (error) { + console.error(error); + throw error; + } +}); test.serial( `${currentTest} should throw an exception when you try delete settings in connection where you do not have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - - const createTableSettingsDTO = mockFactory.generateTableSettings( - testData.connections.secondId, - testData.secondTableInfo.testTableName, - ['id'], - [testData.secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + + const createTableSettingsDTO = mockFactory.generateTableSettings( + testData.connections.secondId, + testData.secondTableInfo.testTableName, + ['id'], + [testData.secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); const createTableSettingsResponse = await request(app.getHttpServer()) .post( `/settings?connectionId=${testData.connections.secondId}&tableName=${testData.secondTableInfo.testTableName}`, ) .send(createTableSettingsDTO) - .set("Cookie", testData.users.adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', testData.users.adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createTableSettingsResponse.status, 201); @@ -4027,12 +3468,10 @@ test.serial( .delete( `/settings/?connectionId=${testData.connections.secondId}&tableName=${testData.secondTableInfo.testTableName}`, ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteTableSettingsRO = JSON.parse( - deleteTableSettingsResponse.text, - ); + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteTableSettingsRO = JSON.parse(deleteTableSettingsResponse.text); t.is(deleteTableSettingsResponse.status, 403); t.is(deleteTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (error) { @@ -4044,153 +3483,112 @@ test.serial( //****************************** TABLE WIDGETS CONTROLLER -currentTest = "GET /widgets/:slug"; - -test.serial( - `${currentTest} should return empty widgets array when widgets not created`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - - const getTableWidgets = await request(app.getHttpServer()) - .get( - `/widgets/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`, - ) - .set("Cookie", testData.users.simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(getTableWidgets.status, 200); - t.is(typeof getTableWidgetsRO, "object"); - t.is(getTableWidgetsRO.length, 0); - } catch (error) { - console.error(error); - throw error; - } - }, -); - -test.serial( - `${currentTest} should return array of table widgets for table`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - undefined, - testData.firstTableInfo.testTableSecondColumnName, - ); +currentTest = 'GET /widgets/:slug'; - const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`, - ) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", testData.users.simpleUserToken) - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 201); - - t.is(typeof createTableWidgetRO, "object"); - t.is(createTableWidgetRO.length, 2); - t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); - t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); - t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); - - const getTableWidgets = await request(app.getHttpServer()) - .get( - `/widgets/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", testData.users.simpleUserToken) - .set("Accept", "application/json"); - t.is(getTableWidgets.status, 200); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(typeof getTableWidgetsRO, "object"); - t.is(getTableWidgetsRO.length, 2); +test.serial(`${currentTest} should return empty widgets array when widgets not created`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) + .set('Cookie', testData.users.simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(getTableWidgets.status, 200); + t.is(typeof getTableWidgetsRO, 'object'); + t.is(getTableWidgetsRO.length, 0); + } catch (error) { + console.error(error); + throw error; + } +}); - t.is(getTableWidgetsRO[0].field_name, newTableWidgets[0].field_name); - t.is(getTableWidgetsRO[0].widget_type, newTableWidgets[0].widget_type); +test.serial(`${currentTest} should return array of table widgets for table`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); - t.is(compareTableWidgetsArrays(getTableWidgetsRO, newTableWidgets), true); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + undefined, + testData.firstTableInfo.testTableSecondColumnName, + ); - const getTableStructureResponse = await request(app.getHttpServer()) - .get( - `/table/structure/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", testData.users.simpleUserToken) - .set("Accept", "application/json"); - t.is(getTableStructureResponse.status, 200); - const getTableStructureRO = JSON.parse(getTableStructureResponse.text); - t.is(Object.hasOwn(getTableStructureRO, "table_widgets"), true); - t.is(getTableStructureRO.table_widgets.length, 2); - t.is( - getTableStructureRO.table_widgets[0].field_name, - newTableWidgets[0].field_name, - ); - t.is( - getTableStructureRO.table_widgets[1].widget_type, - newTableWidgets[1].widget_type, - ); - t.is( - compareTableWidgetsArrays( - getTableStructureRO.table_widgets, - newTableWidgets, - ), - true, - ); - } catch (error) { - console.error(error); - throw error; - } - }, -); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', testData.users.simpleUserToken) + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 201); + + t.is(typeof createTableWidgetRO, 'object'); + t.is(createTableWidgetRO.length, 2); + t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); + t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); + t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); + + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', testData.users.simpleUserToken) + .set('Accept', 'application/json'); + t.is(getTableWidgets.status, 200); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(typeof getTableWidgetsRO, 'object'); + t.is(getTableWidgetsRO.length, 2); + + t.is(getTableWidgetsRO[0].field_name, newTableWidgets[0].field_name); + t.is(getTableWidgetsRO[0].widget_type, newTableWidgets[0].widget_type); + + t.is(compareTableWidgetsArrays(getTableWidgetsRO, newTableWidgets), true); + + const getTableStructureResponse = await request(app.getHttpServer()) + .get(`/table/structure/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', testData.users.simpleUserToken) + .set('Accept', 'application/json'); + t.is(getTableStructureResponse.status, 200); + const getTableStructureRO = JSON.parse(getTableStructureResponse.text); + t.is(Object.hasOwn(getTableStructureRO, 'table_widgets'), true); + t.is(getTableStructureRO.table_widgets.length, 2); + t.is(getTableStructureRO.table_widgets[0].field_name, newTableWidgets[0].field_name); + t.is(getTableStructureRO.table_widgets[1].widget_type, newTableWidgets[1].widget_type); + t.is(compareTableWidgetsArrays(getTableStructureRO.table_widgets, newTableWidgets), true); + } catch (error) { + console.error(error); + throw error; + } +}); test.serial( `${currentTest} should throw an exception, when you try to get widgets from connection, when you do not have permissions`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - undefined, - testData.secondTableInfo.testTableSecondColumnName, - ); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + undefined, + testData.secondTableInfo.testTableSecondColumnName, + ); const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${testData.connections.secondId}?tableName=${testData.secondTableInfo.testTableName}`, - ) + .post(`/widget/${testData.connections.secondId}?tableName=${testData.secondTableInfo.testTableName}`) .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", testData.users.adminUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', testData.users.adminUserToken) + .set('Accept', 'application/json'); const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 201); - t.is(typeof createTableWidgetRO, "object"); + t.is(typeof createTableWidgetRO, 'object'); t.is(createTableWidgetRO.length, 2); t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); const getTableWidgets = await request(app.getHttpServer()) - .get( - `/widgets/${testData.connections.secondId}?tableName=${testData.secondTableInfo.testTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", testData.users.simpleUserToken) - .set("Accept", "application/json"); + .get(`/widgets/${testData.connections.secondId}?tableName=${testData.secondTableInfo.testTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', testData.users.simpleUserToken) + .set('Accept', 'application/json'); const getTableWidgetsRO = JSON.parse(getTableWidgets.text); t.is(getTableWidgets.status, 403); t.is(getTableWidgetsRO.message, Messages.DONT_HAVE_PERMISSIONS); @@ -4201,75 +3599,58 @@ test.serial( }, ); -currentTest = "POST /widget/:slug"; - -test.serial( - `${currentTest} should return table settings with created table widget field`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - undefined, - testData.firstTableInfo.testTableSecondColumnName, - ); - const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`, - ) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", testData.users.simpleUserToken) - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 201); - t.is(typeof createTableWidgetRO, "object"); - - const getTableWidgets = await request(app.getHttpServer()) - .get( - `/widgets/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", testData.users.simpleUserToken) - .set("Accept", "application/json"); - t.is(getTableWidgets.status, 200); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(typeof getTableWidgetsRO, "object"); - t.is(getTableWidgetsRO.length, 2); +currentTest = 'POST /widget/:slug'; - t.is(getTableWidgetsRO[0].widget_type, newTableWidgets[0].widget_type); - t.is(compareTableWidgetsArrays(getTableWidgetsRO, newTableWidgets), true); - } catch (error) { - console.error(error); - throw error; - } - }, -); +test.serial(`${currentTest} should return table settings with created table widget field`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + undefined, + testData.firstTableInfo.testTableSecondColumnName, + ); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', testData.users.simpleUserToken) + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 201); + t.is(typeof createTableWidgetRO, 'object'); + + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${testData.connections.firstId}?tableName=${testData.firstTableInfo.testTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', testData.users.simpleUserToken) + .set('Accept', 'application/json'); + t.is(getTableWidgets.status, 200); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(typeof getTableWidgetsRO, 'object'); + t.is(getTableWidgetsRO.length, 2); + + t.is(getTableWidgetsRO[0].widget_type, newTableWidgets[0].widget_type); + t.is(compareTableWidgetsArrays(getTableWidgetsRO, newTableWidgets), true); + } catch (error) { + console.error(error); + throw error; + } +}); test.serial( `${currentTest} should throw an exception, when you try add widget in connection, when you do not have permissions`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app, - ); - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - undefined, - testData.firstTableInfo.testTableSecondColumnName, - ); + const testData = await createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection(app); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + undefined, + testData.firstTableInfo.testTableSecondColumnName, + ); const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${testData.connections.secondId}?tableName=${testData.firstTableInfo.testTableName}`, - ) + .post(`/widget/${testData.connections.secondId}?tableName=${testData.firstTableInfo.testTableName}`) .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", testData.users.simpleUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', testData.users.simpleUserToken) + .set('Accept', 'application/json'); const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 403); t.is(createTableWidgetRO.message, Messages.DONT_HAVE_PERMISSIONS); diff --git a/backend/test/ava-tests/saas-tests/user-group-edit-permissions-e2e.test.ts b/backend/test/ava-tests/saas-tests/user-group-edit-permissions-e2e.test.ts index 4e2a02e9c..0ab921abf 100644 --- a/backend/test/ava-tests/saas-tests/user-group-edit-permissions-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/user-group-edit-permissions-e2e.test.ts @@ -1,38 +1,34 @@ /* eslint-disable security/detect-object-injection */ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { faker } from "@faker-js/faker"; -import { INestApplication, ValidationPipe } from "@nestjs/common"; -import { Test } from "@nestjs/testing"; -import test from "ava"; -import { ValidationError } from "class-validator"; -import cookieParser from "cookie-parser"; -import request from "supertest"; -import { ApplicationModule } from "../../../src/app.module.js"; -import { WinstonLogger } from "../../../src/entities/logging/winston-logger.js"; -import { - AccessLevelEnum, - QueryOrderingEnum, -} from "../../../src/enums/index.js"; -import { AllExceptionsFilter } from "../../../src/exceptions/all-exceptions.filter.js"; -import { ValidationException } from "../../../src/exceptions/custom-exceptions/validation-exception.js"; -import { Messages } from "../../../src/exceptions/text/messages.js"; -import { Cacher } from "../../../src/helpers/cache/cacher.js"; -import { Constants } from "../../../src/helpers/constants/constants.js"; -import { DatabaseModule } from "../../../src/shared/database/database.module.js"; -import { DatabaseService } from "../../../src/shared/database/database.service.js"; -import { MockFactory } from "../../mock.factory.js"; -import { compareTableWidgetsArrays } from "../../utils/compare-table-widgets-arrays.js"; -import { inviteUserInCompanyAndAcceptInvitation } from "../../utils/register-user-and-return-user-info.js"; -import { TestUtils } from "../../utils/test.utils.js"; -import { createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions } from "../../utils/user-with-different-permissions-utils.js"; +import { faker } from '@faker-js/faker'; +import { INestApplication, ValidationPipe } from '@nestjs/common'; +import { Test } from '@nestjs/testing'; +import test from 'ava'; +import { ValidationError } from 'class-validator'; +import cookieParser from 'cookie-parser'; +import request from 'supertest'; +import { ApplicationModule } from '../../../src/app.module.js'; +import { WinstonLogger } from '../../../src/entities/logging/winston-logger.js'; +import { AccessLevelEnum, QueryOrderingEnum } from '../../../src/enums/index.js'; +import { AllExceptionsFilter } from '../../../src/exceptions/all-exceptions.filter.js'; +import { ValidationException } from '../../../src/exceptions/custom-exceptions/validation-exception.js'; +import { Messages } from '../../../src/exceptions/text/messages.js'; +import { Cacher } from '../../../src/helpers/cache/cacher.js'; +import { Constants } from '../../../src/helpers/constants/constants.js'; +import { DatabaseModule } from '../../../src/shared/database/database.module.js'; +import { DatabaseService } from '../../../src/shared/database/database.service.js'; +import { MockFactory } from '../../mock.factory.js'; +import { compareTableWidgetsArrays } from '../../utils/compare-table-widgets-arrays.js'; +import { inviteUserInCompanyAndAcceptInvitation } from '../../utils/register-user-and-return-user-info.js'; +import { TestUtils } from '../../utils/test.utils.js'; +import { createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions } from '../../utils/user-with-different-permissions-utils.js'; let app: INestApplication; let _testUtils: TestUtils; let currentTest: string; const mockFactory = new MockFactory(); -const newConnectionToPostgres = - mockFactory.generateConnectionToTestPostgresDBInDocker(); +const newConnectionToPostgres = mockFactory.generateConnectionToTestPostgresDBInDocker(); const updateConnection = mockFactory.generateUpdateConnectionDto(); const newGroup1 = mockFactory.generateCreateGroupDto1(); const tablePermissions = { @@ -69,7 +65,7 @@ test.after(async () => { await Cacher.clearAllCache(); await app.close(); } catch (e) { - console.error("After tests error " + e); + console.error('After tests error ' + e); } }); @@ -77,68 +73,57 @@ test.after(async () => { //****************************** CONNECTION CONTROLLER -currentTest = "GET /connections/"; +currentTest = 'GET /connections/'; -test.serial( - `${currentTest} should return connections, where second user have access`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const findAll = await request(app.getHttpServer()) - .get("/connections") - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - - t.is(findAll.status, 200); - - const result = findAll.body.connections; - t.is(result.length, 5); - t.is(Object.hasOwn(result[0], "connection"), true); - t.is(Object.hasOwn(result[0], "accessLevel"), true); - - t.is(Object.hasOwn(result[0], "accessLevel"), true); - t.is(Object.hasOwn(result[0].connection, "host"), true); - t.is(Object.hasOwn(result[0].connection, "host"), true); - t.is(typeof result[0].connection.port, "number"); - t.is(Object.hasOwn(result[0].connection, "port"), true); - t.is(Object.hasOwn(result[0].connection, "username"), true); - t.is(Object.hasOwn(result[0].connection, "database"), true); - t.is(Object.hasOwn(result[0].connection, "sid"), true); - t.is(Object.hasOwn(result[0].connection, "createdAt"), true); - t.is(Object.hasOwn(result[0].connection, "updatedAt"), true); - t.is(Object.hasOwn(result[0].connection, "password"), false); - t.is(Object.hasOwn(result[0].connection, "groups"), false); - t.is(Object.hasOwn(result[0].connection, "author"), false); - const testConnectionsCount = result.filter( - (el: any) => el.connection.isTestConnection, - ).length; - t.is(testConnectionsCount, 4); - } catch (e) { - console.error(e); - } - }, -); +test.serial(`${currentTest} should return connections, where second user have access`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const findAll = await request(app.getHttpServer()) + .get('/connections') + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + + t.is(findAll.status, 200); + + const result = findAll.body.connections; + t.is(result.length, 5); + t.is(Object.hasOwn(result[0], 'connection'), true); + t.is(Object.hasOwn(result[0], 'accessLevel'), true); + + t.is(Object.hasOwn(result[0], 'accessLevel'), true); + t.is(Object.hasOwn(result[0].connection, 'host'), true); + t.is(Object.hasOwn(result[0].connection, 'host'), true); + t.is(typeof result[0].connection.port, 'number'); + t.is(Object.hasOwn(result[0].connection, 'port'), true); + t.is(Object.hasOwn(result[0].connection, 'username'), true); + t.is(Object.hasOwn(result[0].connection, 'database'), true); + t.is(Object.hasOwn(result[0].connection, 'sid'), true); + t.is(Object.hasOwn(result[0].connection, 'createdAt'), true); + t.is(Object.hasOwn(result[0].connection, 'updatedAt'), true); + t.is(Object.hasOwn(result[0].connection, 'password'), false); + t.is(Object.hasOwn(result[0].connection, 'groups'), false); + t.is(Object.hasOwn(result[0].connection, 'author'), false); + const testConnectionsCount = result.filter((el: any) => el.connection.isTestConnection).length; + t.is(testConnectionsCount, 4); + } catch (e) { + console.error(e); + } +}); -currentTest = "GET /connection/one/:slug"; +currentTest = 'GET /connection/one/:slug'; test.serial(`${currentTest} should return a found connection`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -151,26 +136,26 @@ test.serial(`${currentTest} should return a found connection`, async (t) => { const searchedConnectionId = connections.firstId; const findOneResponce = await request(app.getHttpServer()) .get(`/connection/one/${searchedConnectionId}`) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); t.is(findOneResponce.status, 200); const result = findOneResponce.body.connection; t.is(result.title, newConnectionToPostgres.title); - t.is(result.type, "postgres"); + t.is(result.type, 'postgres'); t.is(result.host, newConnectionToPostgres.host); - t.is(typeof result.port, "number"); + t.is(typeof result.port, 'number'); t.is(result.port, newConnectionToPostgres.port); - t.is(result.username, "postgres"); + t.is(result.username, 'postgres'); t.is(result.database, newConnectionToPostgres.database); t.is(result.sid, null); - t.is(Object.hasOwn(result, "createdAt"), true); - t.is(Object.hasOwn(result, "updatedAt"), true); - t.is(Object.hasOwn(result, "password"), false); - t.is(Object.hasOwn(result, "groups"), false); - t.is(Object.hasOwn(result, "author"), false); + t.is(Object.hasOwn(result, 'createdAt'), true); + t.is(Object.hasOwn(result, 'updatedAt'), true); + t.is(Object.hasOwn(result, 'password'), false); + t.is(Object.hasOwn(result, 'groups'), false); + t.is(Object.hasOwn(result, 'author'), false); } catch (e) { console.error(e); } @@ -180,10 +165,7 @@ test.serial( `${currentTest} should throw an exception, when you do not have permission in this connection`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -197,65 +179,53 @@ test.serial( const findOneResponce = await request(app.getHttpServer()) .get(`/connection/one/${searchedConnectionId}`) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); // todo add checking connection object properties t.is(findOneResponce.status, 200); const findOneRO = JSON.parse(findOneResponce.text); - t.is(Object.hasOwn(findOneRO, "host"), false); + t.is(Object.hasOwn(findOneRO, 'host'), false); } catch (e) { console.error(e); } }, ); -currentTest = "PUT /connection"; +currentTest = 'PUT /connection'; -test.serial( - `${currentTest} should throw exception you do not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw exception you do not have permission`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const updateConnectionResponse = await request(app.getHttpServer()) - .put(`/connection/${connections.firstId}`) - .send(updateConnection) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const updateConnectionResponse = await request(app.getHttpServer()) + .put(`/connection/${connections.firstId}`) + .send(updateConnection) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(updateConnectionResponse.status, 403); - t.is( - JSON.parse(updateConnectionResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); - } catch (e) { - console.error(e); - } - }, -); + t.is(updateConnectionResponse.status, 403); + t.is(JSON.parse(updateConnectionResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + } +}); test.serial( `${currentTest} should return throw an exception, when you try update a connection without permissions in it`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -267,71 +237,59 @@ test.serial( const updateConnectionResponse = await request(app.getHttpServer()) .put(`/connection/${connections.secondId}`) .send(updateConnection) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(updateConnectionResponse.status, 403); - t.is( - JSON.parse(updateConnectionResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + t.is(JSON.parse(updateConnectionResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); } }, ); -currentTest = "DELETE /connection/:slug"; - -test.serial( - `${currentTest} should throw an exception do not have permissions`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +currentTest = 'DELETE /connection/:slug'; - const response = await request(app.getHttpServer()) - .put(`/connection/delete/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(response.status, 403); - t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); +test.serial(`${currentTest} should throw an exception do not have permissions`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - //deleted connection found in database - const findOneResponce = await request(app.getHttpServer()) - .get(`/connection/one/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const response = await request(app.getHttpServer()) + .put(`/connection/delete/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(response.status, 403); + t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); + + //deleted connection found in database + const findOneResponce = await request(app.getHttpServer()) + .get(`/connection/one/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(findOneResponce.status, 200); - t.is(JSON.parse(findOneResponce.text).connection.id, connections.firstId); - } catch (e) { - console.error(e); - } - }, -); + t.is(findOneResponce.status, 200); + t.is(JSON.parse(findOneResponce.text).connection.id, connections.firstId); + } catch (e) { + console.error(e); + } +}); test.serial( `${currentTest} should throw an exception, when you try to delete connection without permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -343,18 +301,18 @@ test.serial( const response = await request(app.getHttpServer()) .put(`/connection/delete/${connections.secondId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 403); t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); //connection wasn't deleted const findOneResponce = await request(app.getHttpServer()) .get(`/connection/one/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(findOneResponce.status, 200); } catch (e) { @@ -363,51 +321,39 @@ test.serial( }, ); -currentTest = "POST /connection/group/:slug"; +currentTest = 'POST /connection/group/:slug'; -test.serial( - `${currentTest} should throw an exception don not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw an exception don not have permission`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 403); - t.is( - JSON.parse(createGroupResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); - } catch (e) { - console.error(e); - } - }, -); + t.is(createGroupResponse.status, 403); + t.is(JSON.parse(createGroupResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + } +}); test.serial( `${currentTest} should throw an exception when you try add group in connection without permission in it`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -418,84 +364,72 @@ test.serial( } = testData; const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.secondId}`) - .set("Cookie", simpleUserToken) + .set('Cookie', simpleUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createGroupResponse.status, 403); - t.is( - JSON.parse(createGroupResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + t.is(JSON.parse(createGroupResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); } }, ); -currentTest = "PUT /connection/group/:slug"; +currentTest = 'PUT /connection/group/:slug'; -test.serial( - `${currentTest} should return connection without deleted group result`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should return connection without deleted group result`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connections.firstId}`) - .set("Cookie", adminUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connections.firstId}`) + .set('Cookie', adminUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - // create group in connection - let result = createGroupResponse.body; - t.is(createGroupResponse.status, 201); + // create group in connection + let result = createGroupResponse.body; + t.is(createGroupResponse.status, 201); - t.is(Object.hasOwn(result, "id"), true); - t.is(result.title, newGroup1.title); + t.is(Object.hasOwn(result, 'id'), true); + t.is(result.title, newGroup1.title); - const createGroupRO = JSON.parse(createGroupResponse.text); + const createGroupRO = JSON.parse(createGroupResponse.text); - const response = await request(app.getHttpServer()) - .put(`/connection/group/delete/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .send({ groupId: createGroupRO.id }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const response = await request(app.getHttpServer()) + .put(`/connection/group/delete/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .send({ groupId: createGroupRO.id }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - //after deleting group - result = response.body; + //after deleting group + result = response.body; - t.is(response.status, 403); - t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - } - }, -); + t.is(response.status, 403); + t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + } +}); test.serial( `${currentTest} should throw an exception, when you try delete group in connection without permissions`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -506,27 +440,27 @@ test.serial( } = testData; const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.secondId}`) - .set("Cookie", adminUserToken) + .set('Cookie', adminUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); // create group in connection const result = createGroupResponse.body; t.is(createGroupResponse.status, 201); - t.is(Object.hasOwn(result, "id"), true); + t.is(Object.hasOwn(result, 'id'), true); t.is(result.title, newGroup1.title); const createGroupRO = JSON.parse(createGroupResponse.text); const response = await request(app.getHttpServer()) .put(`/connection/group/delete/${connections.secondId}`) - .set("Cookie", simpleUserToken) + .set('Cookie', simpleUserToken) .send({ groupId: createGroupRO.id }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 403); t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); @@ -536,14 +470,11 @@ test.serial( }, ); -currentTest = "GET /connection/groups/:slug"; +currentTest = 'GET /connection/groups/:slug'; test.serial(`${currentTest} should groups in connection`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -557,28 +488,28 @@ test.serial(`${currentTest} should groups in connection`, async (t) => { const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.firstId}`) - .set("Cookie", adminUserToken) + .set('Cookie', adminUserToken) .send(newRandomGroup2) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createGroupResponse.status, 201); const response = await request(app.getHttpServer()) .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 200); const result = JSON.parse(response.text); const _groupId = result[0].group.id; - t.is(Object.hasOwn(result[0].group, "title"), true); + t.is(Object.hasOwn(result[0].group, 'title'), true); t.is(result[0].accessLevel, AccessLevelEnum.edit); const index = result.findIndex((el: any) => { - return el.group.title === "Admin"; + return el.group.title === 'Admin'; }); t.is(index >= 0, false); @@ -591,10 +522,7 @@ test.serial( `${currentTest} it should throw an exception, when you try get groups in connection, where you do not have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -605,18 +533,18 @@ test.serial( } = testData; const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.secondId}`) - .set("Cookie", adminUserToken) + .set('Cookie', adminUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createGroupResponse.status, 201); const response = await request(app.getHttpServer()) .get(`/connection/groups/${connections.secondId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 200); const result = JSON.parse(response.text); @@ -627,16 +555,124 @@ test.serial( }, ); -currentTest = "GET /connection/permissions"; +currentTest = 'GET /connection/permissions'; + +test.serial(`${currentTest} should return permissions object for current group in current connection`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const groupId = getGroupsRO[0].group.id; + + const response = await request(app.getHttpServer()) + .get(`/connection/permissions?connectionId=${connections.firstId}&groupId=${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const result = JSON.parse(response.text); + t.is(response.status, 200); + + t.is(Object.hasOwn(result, 'connection'), true); + t.is(Object.hasOwn(result, 'group'), true); + t.is(Object.hasOwn(result, 'tables'), true); + t.is(typeof result.connection, 'object'); + t.is(typeof result.group, 'object'); + t.is(result.connection.connectionId, connections.firstId); + t.is(result.group.groupId, groupId); + t.is(result.connection.accessLevel, AccessLevelEnum.readonly); + t.is(result.group.accessLevel, AccessLevelEnum.edit); + t.is(typeof result.tables, 'object'); + + const { tables } = result; + const tableIndex = tables.findIndex((table: any) => table.tableName === firstTableInfo.testTableName); + t.is(tables.length > 0, true); + t.is(typeof tables[tableIndex], 'object'); + t.is(Object.hasOwn(tables[tableIndex], 'accessLevel'), true); + t.is(tables[tableIndex].accessLevel.visibility, tablePermissions.visibility); + t.is(tables[tableIndex].accessLevel.readonly, tablePermissions.readonly); + t.is(tables[tableIndex].accessLevel.add, tablePermissions.add); + t.is(tables[tableIndex].accessLevel.delete, tablePermissions.delete); + t.is(tables[tableIndex].accessLevel.edit, tablePermissions.edit); + } catch (e) { + console.error(e); + } +}); + +currentTest = 'GET /connection/user/permissions'; + +test.serial(`${currentTest} should return permissions object for current group in current connection`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const groupId = getGroupsRO[0].group.id; + + const response = await request(app.getHttpServer()) + .get(`/connection/user/permissions?connectionId=${connections.firstId}&groupId=${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(response.status, 200); + const result = JSON.parse(response.text); + + t.is(Object.hasOwn(result, 'connection'), true); + t.is(Object.hasOwn(result, 'group'), true); + t.is(Object.hasOwn(result, 'tables'), true); + t.is(typeof result.connection, 'object'); + t.is(typeof result.group, 'object'); + t.is(result.connection.connectionId, connections.firstId); + t.is(result.group.groupId, groupId); + t.is(result.connection.accessLevel, AccessLevelEnum.readonly); + t.is(result.group.accessLevel, AccessLevelEnum.edit); + t.is(typeof result.tables, 'object'); + + const { tables } = result; + const foundTableIndex = tables.findIndex((table) => table.tableName === firstTableInfo.testTableName); + t.is(tables.length > 0, true); + t.is(typeof tables[foundTableIndex], 'object'); + t.is(Object.hasOwn(tables[foundTableIndex], 'accessLevel'), true); + t.is(tables[foundTableIndex].accessLevel.visibility, tablePermissions.visibility); + t.is(tables[foundTableIndex].accessLevel.readonly, tablePermissions.readonly); + t.is(tables[foundTableIndex].accessLevel.add, tablePermissions.add); + t.is(tables[foundTableIndex].accessLevel.delete, tablePermissions.delete); + t.is(tables[foundTableIndex].accessLevel.edit, tablePermissions.edit); + } catch (e) { + console.error(e); + } +}); test.serial( - `${currentTest} should return permissions object for current group in current connection`, + `${currentTest} should return permissions object for current group in current connection for current user`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -645,242 +681,89 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; + const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/connection/groups/${connections.secondId}`) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); + const groupId = getGroupsRO[0].group.id; const response = await request(app.getHttpServer()) - .get( - `/connection/permissions?connectionId=${connections.firstId}&groupId=${groupId}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const result = JSON.parse(response.text); + .get(`/connection/user/permissions?connectionId=${connections.secondId}&groupId=${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(response.status, 200); + const result = JSON.parse(response.text); - t.is(Object.hasOwn(result, "connection"), true); - t.is(Object.hasOwn(result, "group"), true); - t.is(Object.hasOwn(result, "tables"), true); - t.is(typeof result.connection, "object"); - t.is(typeof result.group, "object"); - t.is(result.connection.connectionId, connections.firstId); + t.is(Object.hasOwn(result, 'connection'), true); + t.is(Object.hasOwn(result, 'group'), true); + t.is(Object.hasOwn(result, 'tables'), true); + t.is(typeof result.connection, 'object'); + t.is(typeof result.group, 'object'); + t.is(result.connection.connectionId, connections.secondId); t.is(result.group.groupId, groupId); - t.is(result.connection.accessLevel, AccessLevelEnum.readonly); - t.is(result.group.accessLevel, AccessLevelEnum.edit); - t.is(typeof result.tables, "object"); + t.is(result.connection.accessLevel, AccessLevelEnum.none); + t.is(result.group.accessLevel, AccessLevelEnum.none); + t.is(typeof result.tables, 'object'); const { tables } = result; - const tableIndex = tables.findIndex( - (table: any) => table.tableName === firstTableInfo.testTableName, - ); + const foundTableIndex = tables.findIndex((table) => table.tableName === firstTableInfo.testTableName); t.is(tables.length > 0, true); - t.is(typeof tables[tableIndex], "object"); - t.is(Object.hasOwn(tables[tableIndex], "accessLevel"), true); - t.is( - tables[tableIndex].accessLevel.visibility, - tablePermissions.visibility, - ); - t.is(tables[tableIndex].accessLevel.readonly, tablePermissions.readonly); - t.is(tables[tableIndex].accessLevel.add, tablePermissions.add); - t.is(tables[tableIndex].accessLevel.delete, tablePermissions.delete); - t.is(tables[tableIndex].accessLevel.edit, tablePermissions.edit); + t.is(typeof tables[0], 'object'); + t.is(Object.hasOwn(tables[foundTableIndex], 'accessLevel'), true); + t.is(tables[foundTableIndex].accessLevel.visibility, false); + t.is(tables[foundTableIndex].accessLevel.readonly, false); + t.is(tables[foundTableIndex].accessLevel.add, false); + t.is(tables[foundTableIndex].accessLevel.delete, false); + t.is(tables[foundTableIndex].accessLevel.edit, false); + t.is(tables[foundTableIndex].accessLevel.edit, false); } catch (e) { console.error(e); } }, ); -currentTest = "GET /connection/user/permissions"; +//****************************** GROUP CONTROLLER ******************************// -test.serial( - `${currentTest} should return permissions object for current group in current connection`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - const groupId = getGroupsRO[0].group.id; - - const response = await request(app.getHttpServer()) - .get( - `/connection/user/permissions?connectionId=${connections.firstId}&groupId=${groupId}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(response.status, 200); - const result = JSON.parse(response.text); - - t.is(Object.hasOwn(result, "connection"), true); - t.is(Object.hasOwn(result, "group"), true); - t.is(Object.hasOwn(result, "tables"), true); - t.is(typeof result.connection, "object"); - t.is(typeof result.group, "object"); - t.is(result.connection.connectionId, connections.firstId); - t.is(result.group.groupId, groupId); - t.is(result.connection.accessLevel, AccessLevelEnum.readonly); - t.is(result.group.accessLevel, AccessLevelEnum.edit); - t.is(typeof result.tables, "object"); - - const { tables } = result; - const foundTableIndex = tables.findIndex( - (table) => table.tableName === firstTableInfo.testTableName, - ); - t.is(tables.length > 0, true); - t.is(typeof tables[foundTableIndex], "object"); - t.is(Object.hasOwn(tables[foundTableIndex], "accessLevel"), true); - t.is( - tables[foundTableIndex].accessLevel.visibility, - tablePermissions.visibility, - ); - t.is( - tables[foundTableIndex].accessLevel.readonly, - tablePermissions.readonly, - ); - t.is(tables[foundTableIndex].accessLevel.add, tablePermissions.add); - t.is(tables[foundTableIndex].accessLevel.delete, tablePermissions.delete); - t.is(tables[foundTableIndex].accessLevel.edit, tablePermissions.edit); - } catch (e) { - console.error(e); - } - }, -); - -test.serial( - `${currentTest} should return permissions object for current group in current connection for current user`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.secondId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - - const groupId = getGroupsRO[0].group.id; - - const response = await request(app.getHttpServer()) - .get( - `/connection/user/permissions?connectionId=${connections.secondId}&groupId=${groupId}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(response.status, 200); - const result = JSON.parse(response.text); - - t.is(Object.hasOwn(result, "connection"), true); - t.is(Object.hasOwn(result, "group"), true); - t.is(Object.hasOwn(result, "tables"), true); - t.is(typeof result.connection, "object"); - t.is(typeof result.group, "object"); - t.is(result.connection.connectionId, connections.secondId); - t.is(result.group.groupId, groupId); - t.is(result.connection.accessLevel, AccessLevelEnum.none); - t.is(result.group.accessLevel, AccessLevelEnum.none); - t.is(typeof result.tables, "object"); - - const { tables } = result; - const foundTableIndex = tables.findIndex( - (table) => table.tableName === firstTableInfo.testTableName, - ); - t.is(tables.length > 0, true); - t.is(typeof tables[0], "object"); - t.is(Object.hasOwn(tables[foundTableIndex], "accessLevel"), true); - t.is(tables[foundTableIndex].accessLevel.visibility, false); - t.is(tables[foundTableIndex].accessLevel.readonly, false); - t.is(tables[foundTableIndex].accessLevel.add, false); - t.is(tables[foundTableIndex].accessLevel.delete, false); - t.is(tables[foundTableIndex].accessLevel.edit, false); - t.is(tables[foundTableIndex].accessLevel.edit, false); - } catch (e) { - console.error(e); - } - }, -); - -//****************************** GROUP CONTROLLER ******************************// - -currentTest = "GET /groups/"; +currentTest = 'GET /groups/'; -test.serial( - `${currentTest} should return found groups with current user`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - users: { simpleUserToken }, - } = testData; +test.serial(`${currentTest} should return found groups with current user`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + users: { simpleUserToken }, + } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/groups/`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - const { groups, groupsCount } = getGroupsRO; - t.is(groupsCount, 1); - t.is(groups.length, 1); - t.is(Object.hasOwn(groups[0], "group"), true); - t.is(Object.hasOwn(groups[0], "accessLevel"), true); - - t.is(Object.hasOwn(groups[0].group, "title"), true); - t.is(Object.hasOwn(groups[0].group, "isMain"), true); - } catch (e) { - console.error(e); - } - }, -); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/groups/`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const { groups, groupsCount } = getGroupsRO; + t.is(groupsCount, 1); + t.is(groups.length, 1); + t.is(Object.hasOwn(groups[0], 'group'), true); + t.is(Object.hasOwn(groups[0], 'accessLevel'), true); + + t.is(Object.hasOwn(groups[0].group, 'title'), true); + t.is(Object.hasOwn(groups[0].group, 'isMain'), true); + } catch (e) { + console.error(e); + } +}); -currentTest = "GET /group/users/:slug"; +currentTest = 'GET /group/users/:slug'; test.serial(`${currentTest} it should return users in group`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -891,9 +774,9 @@ test.serial(`${currentTest} it should return users in group`, async (t) => { } = testData; const getGroupsResponse = await request(app.getHttpServer()) .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); const nonAdminGroupIndex = getGroupsRO.findIndex((element) => { @@ -902,16 +785,16 @@ test.serial(`${currentTest} it should return users in group`, async (t) => { const groupId = getGroupsRO[nonAdminGroupIndex].group.id; const response = await request(app.getHttpServer()) .get(`/group/users/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getUsersRO = JSON.parse(response.text); t.is(getUsersRO.length, 2); t.is(getUsersRO[0].id === getUsersRO[1].id, false); - t.is(Object.hasOwn(getUsersRO[0], "createdAt"), true); - t.is(Object.hasOwn(getUsersRO[0], "password"), false); - t.is(Object.hasOwn(getUsersRO[0], "isActive"), true); - t.is(Object.hasOwn(getUsersRO[0], "email"), true); + t.is(Object.hasOwn(getUsersRO[0], 'createdAt'), true); + t.is(Object.hasOwn(getUsersRO[0], 'password'), false); + t.is(Object.hasOwn(getUsersRO[0], 'isActive'), true); + t.is(Object.hasOwn(getUsersRO[0], 'email'), true); } catch (e) { console.error(e); } @@ -921,10 +804,7 @@ test.serial( `${currentTest} it should throw an exception when you try to receive user in group where you dont have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -935,9 +815,9 @@ test.serial( } = testData; const getGroupsResponse = await request(app.getHttpServer()) .get(`/connection/groups/${connections.secondId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); @@ -945,9 +825,9 @@ test.serial( const response = await request(app.getHttpServer()) .get(`/group/users/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getUsersRO = JSON.parse(response.text); t.is(getUsersRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { @@ -956,14 +836,11 @@ test.serial( }, ); -currentTest = "PUT /group/user"; +currentTest = 'PUT /group/user'; test.serial(`${currentTest} should return group with added user`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -975,9 +852,9 @@ test.serial(`${currentTest} should return group with added user`, async (t) => { const getGroupsResponse = await request(app.getHttpServer()) .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); @@ -986,16 +863,16 @@ test.serial(`${currentTest} should return group with added user`, async (t) => { const email = faker.internet.email(); const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", simpleUserToken) + .put('/group/user') + .set('Cookie', simpleUserToken) .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text).group; - t.is(Object.hasOwn(addUserInGroupRO, "title"), true); - t.is(Object.hasOwn(addUserInGroupRO, "isMain"), true); - t.is(Object.hasOwn(addUserInGroupRO, "users"), true); + t.is(Object.hasOwn(addUserInGroupRO, 'title'), true); + t.is(Object.hasOwn(addUserInGroupRO, 'isMain'), true); + t.is(Object.hasOwn(addUserInGroupRO, 'users'), true); const { users } = addUserInGroupRO; t.is(users.length, 3); t.is(users[0].id === users[1].id, false); @@ -1006,589 +883,506 @@ test.serial(`${currentTest} should return group with added user`, async (t) => { } }); -test.serial( - `${currentTest} should throw exception, when user email not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw exception, when user email not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const groupId = getGroupsRO[0].group.id; - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", simpleUserToken) - .send({ groupId }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const _addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); - t.is(addUserInGroupResponse.status, 400); - // t.is(addUserInGroupRO.message, ErrorsMessages.VALIDATION_FAILED); - } catch (e) { - console.error(e); - } - }, -); + const groupId = getGroupsRO[0].group.id; + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', simpleUserToken) + .send({ groupId }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const _addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); + t.is(addUserInGroupResponse.status, 400); + // t.is(addUserInGroupRO.message, ErrorsMessages.VALIDATION_FAILED); + } catch (e) { + console.error(e); + } +}); -test.serial( - `${currentTest} should throw exception, when group id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw exception, when group id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const _groupId = getGroupsRO[0].group.id; - const email = faker.internet.email(); - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", simpleUserToken) - .send({ email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); - t.is(addUserInGroupResponse.status, 400); - t.is(addUserInGroupRO.message, Messages.GROUP_ID_MISSING); - } catch (e) { - console.error(e); - } - }, -); + const _groupId = getGroupsRO[0].group.id; + const email = faker.internet.email(); + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', simpleUserToken) + .send({ email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); + t.is(addUserInGroupResponse.status, 400); + t.is(addUserInGroupRO.message, Messages.GROUP_ID_MISSING); + } catch (e) { + console.error(e); + } +}); -test.serial( - `${currentTest} should throw exception, when group id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw exception, when group id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); - const _getGroupsRO = JSON.parse(getGroupsResponse.text); - - const email = faker.internet.email(); - const groupId = faker.string.uuid(); - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); - t.is(addUserInGroupResponse.status, 400); - t.is(addUserInGroupRO.message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - } - }, -); + t.is(getGroupsResponse.status, 200); + const _getGroupsRO = JSON.parse(getGroupsResponse.text); -currentTest = "DELETE /group/:slug"; + const email = faker.internet.email(); + const groupId = faker.string.uuid(); + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); + t.is(addUserInGroupResponse.status, 400); + t.is(addUserInGroupRO.message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + } +}); -test.serial( - `${currentTest} should delete result after group deletion`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +currentTest = 'DELETE /group/:slug'; - t.is(getGroupsResponse.status, 200); +test.serial(`${currentTest} should delete result after group deletion`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const groupId = JSON.parse(getGroupsResponse.text)[0].group.id; - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteGroupRO = JSON.parse(deleteGroupResponse.text); - t.is(deleteGroupRO.isMain, false); - } catch (e) { - console.error(e); - } - }, -); + t.is(getGroupsResponse.status, 200); -test.serial( - `${currentTest} should throw an exception when you try delete admin group`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const groupId = JSON.parse(getGroupsResponse.text)[0].group.id; + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteGroupRO = JSON.parse(deleteGroupResponse.text); + t.is(deleteGroupRO.isMain, false); + } catch (e) { + console.error(e); + } +}); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); +test.serial(`${currentTest} should throw an exception when you try delete admin group`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const adminGroupIndex = getGroupsRO.findIndex( - (group) => group.group.isMain, - ); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const groupId = getGroupsRO[adminGroupIndex].group.id; - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteGroupRO = JSON.parse(deleteGroupResponse.text); - t.is(deleteGroupRO.message, Messages.CANT_DELETE_ADMIN_GROUP); - } catch (e) { - console.error(e); - } - }, -); + const adminGroupIndex = getGroupsRO.findIndex((group) => group.group.isMain); -test.serial( - `${currentTest} should throw an exception when group id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const groupId = getGroupsRO[adminGroupIndex].group.id; + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteGroupRO = JSON.parse(deleteGroupResponse.text); + t.is(deleteGroupRO.message, Messages.CANT_DELETE_ADMIN_GROUP); + } catch (e) { + console.error(e); + } +}); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); +test.serial(`${currentTest} should throw an exception when group id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const _groupId = getGroupsRO[0].group.id; - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(deleteGroupResponse.status, 404); - } catch (e) { - console.error(e); - } - }, -); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); -test.serial( - `${currentTest} should throw an exception when group id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const _groupId = getGroupsRO[0].group.id; + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(deleteGroupResponse.status, 404); + } catch (e) { + console.error(e); + } +}); - t.is(getGroupsResponse.status, 200); +test.serial(`${currentTest} should throw an exception when group id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const groupId = faker.string.uuid(); - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteGroupRO = JSON.parse(deleteGroupResponse.text); - t.is(deleteGroupRO.message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - } - }, -); + t.is(getGroupsResponse.status, 200); -currentTest = "PUT /group/user/delete"; + const groupId = faker.string.uuid(); + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteGroupRO = JSON.parse(deleteGroupResponse.text); + t.is(deleteGroupRO.message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + } +}); -test.serial( - `${currentTest} should return group without deleted user`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +currentTest = 'PUT /group/user/delete'; - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); +test.serial(`${currentTest} should return group without deleted user`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const groupId = getGroupsRO[0].group.id; + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( - testData.users.adminUserToken, - undefined, - app, - undefined, - ); + const groupId = getGroupsRO[0].group.id; - const email = thirdTestUser.email; - - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", testData.users.simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(addUserInGroupResponse.status, 200); - - const deleteUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user/delete") - .set("Cookie", simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); - - t.is(Object.hasOwn(deleteUserInGroupRO, "title"), true); - t.is(Object.hasOwn(deleteUserInGroupRO, "isMain"), true); - t.is(Object.hasOwn(deleteUserInGroupRO, "users"), true); - const { users } = deleteUserInGroupRO; - t.is(users.length, 2); - t.is(users[0].id === users[1].id, false); - } catch (e) { - console.error(e); - } - }, -); + const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( + testData.users.adminUserToken, + undefined, + app, + undefined, + ); -test.serial( - `${currentTest} should throw exception, when user email not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const email = thirdTestUser.email; - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', testData.users.simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addUserInGroupResponse.status, 200); - const groupId = getGroupsRO[0].group.id; + const deleteUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user/delete') + .set('Cookie', simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); + + t.is(Object.hasOwn(deleteUserInGroupRO, 'title'), true); + t.is(Object.hasOwn(deleteUserInGroupRO, 'isMain'), true); + t.is(Object.hasOwn(deleteUserInGroupRO, 'users'), true); + const { users } = deleteUserInGroupRO; + t.is(users.length, 2); + t.is(users[0].id === users[1].id, false); + } catch (e) { + console.error(e); + } +}); - const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( - testData.users.adminUserToken, - undefined, - app, - undefined, - ); +test.serial(`${currentTest} should throw exception, when user email not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const _email = thirdTestUser.email; + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const deleteUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user/delete") - .set("Cookie", simpleUserToken) - .send({ groupId }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const _deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); - // t.is(deleteUserInGroupRO.message, ErrorsMessages.VALIDATION_FAILED); - } catch (e) { - console.error(e); - } - }, -); + const groupId = getGroupsRO[0].group.id; -test.serial( - `${currentTest} should throw exception, when group id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( + testData.users.adminUserToken, + undefined, + app, + undefined, + ); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + const _email = thirdTestUser.email; - const _groupId = getGroupsRO[0].group.id; + const deleteUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user/delete') + .set('Cookie', simpleUserToken) + .send({ groupId }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const _deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); + // t.is(deleteUserInGroupRO.message, ErrorsMessages.VALIDATION_FAILED); + } catch (e) { + console.error(e); + } +}); - const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( - testData.users.adminUserToken, - undefined, - app, - undefined, - ); +test.serial(`${currentTest} should throw exception, when group id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const email = thirdTestUser.email; + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const deleteUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user/delete") - .set("Cookie", simpleUserToken) - .send({ email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); - t.is(deleteUserInGroupRO.message, Messages.GROUP_ID_MISSING); - } catch (e) { - console.error(e); - } - }, -); + const _groupId = getGroupsRO[0].group.id; -test.serial( - `${currentTest} should throw exception, when group id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( + testData.users.adminUserToken, + undefined, + app, + undefined, + ); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + const email = thirdTestUser.email; - let groupId = getGroupsRO[0].group.id; + const deleteUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user/delete') + .set('Cookie', simpleUserToken) + .send({ email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); + t.is(deleteUserInGroupRO.message, Messages.GROUP_ID_MISSING); + } catch (e) { + console.error(e); + } +}); - const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( - testData.users.adminUserToken, - undefined, - app, - undefined, - ); +test.serial(`${currentTest} should throw exception, when group id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const email = thirdTestUser.email; - - groupId = faker.string.uuid(); - const deleteUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user/delete") - .set("Cookie", simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); - t.is(deleteUserInGroupRO.message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - } - }, -); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + + let groupId = getGroupsRO[0].group.id; + + const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( + testData.users.adminUserToken, + undefined, + app, + undefined, + ); + + const email = thirdTestUser.email; + + groupId = faker.string.uuid(); + const deleteUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user/delete') + .set('Cookie', simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); + t.is(deleteUserInGroupRO.message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + } +}); //****************************** PERMISSION CONTROLLER TESTS ******************************// -currentTest = "PUT permissions/:slug"; +currentTest = 'PUT permissions/:slug'; -test.serial( - `${currentTest} should throw an exception do not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connections.firstId}`) - .set("Cookie", adminUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - t.is(createGroupResponse.status, 201); - const newGroupId = createGroupRO.id; +test.serial(`${currentTest} should throw an exception do not have permission`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connections.firstId}`) + .set('Cookie', adminUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + t.is(createGroupResponse.status, 201); + const newGroupId = createGroupRO.id; - const permissions = { - connection: { - connectionId: connections.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, - }, - tables: [ - { - tableName: firstTableInfo.testTableName, - accessLevel: { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: false, - }, + const permissions = { + connection: { + connectionId: connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: firstTableInfo.testTableName, + accessLevel: { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: false, }, - ], - }; - - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createOrUpdatePermissionRO = JSON.parse( - createOrUpdatePermissionResponse.text, - ); - t.is(createOrUpdatePermissionResponse.status, 403); - t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - } - }, -); + }, + ], + }; + + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createOrUpdatePermissionRO = JSON.parse(createOrUpdatePermissionResponse.text); + t.is(createOrUpdatePermissionResponse.status, 403); + t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + } +}); test.serial( `${currentTest} should return updated complex permissions object when you update permissions`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -1599,205 +1393,166 @@ test.serial( const getGroupsResponse = await request(app.getHttpServer()) .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); - const groupId = getGroupsRO[0].group.id; - - const permissions = { - connection: { - accessLevel: AccessLevelEnum.none, - connectionId: connections.firstId, - }, - group: { - accessLevel: AccessLevelEnum.readonly, - groupId: groupId, - }, - tables: [ - { - accessLevel: { - add: false, - delete: false, - edit: true, - readonly: false, - visibility: true, - }, - tableName: firstTableInfo.testTableName, - }, - ], - }; - - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put(`/permissions/${groupId}?connectionId=${connections.firstId}`) - .send({ permissions }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const _createOrUpdatePermissionRO = JSON.parse( - createOrUpdatePermissionResponse.text, - ); - t.is(createOrUpdatePermissionResponse.status, 403); - } catch (e) { - console.error(e); - } - }, -); - -test.serial( - `${currentTest} should throw an exception, when you try change admin group`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups: { firstAdminGroupId }, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; + const groupId = getGroupsRO[0].group.id; const permissions = { connection: { + accessLevel: AccessLevelEnum.none, connectionId: connections.firstId, - accessLevel: AccessLevelEnum.edit, }, group: { - groupId: firstAdminGroupId, - accessLevel: AccessLevelEnum.none, + accessLevel: AccessLevelEnum.readonly, + groupId: groupId, }, tables: [ { - tableName: firstTableInfo.testTableName, accessLevel: { - visibility: true, + add: false, + delete: false, + edit: true, readonly: false, - add: true, - delete: true, - edit: false, + visibility: true, }, + tableName: firstTableInfo.testTableName, }, ], }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put(`/permissions/${firstAdminGroupId}`) + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${groupId}?connectionId=${connections.firstId}`) .send({ permissions }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createOrUpdatePermissionRO = JSON.parse( - createOrUpdatePermissionResponse.text, - ); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const _createOrUpdatePermissionRO = JSON.parse(createOrUpdatePermissionResponse.text); t.is(createOrUpdatePermissionResponse.status, 403); - t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); } }, ); +test.serial(`${currentTest} should throw an exception, when you try change admin group`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups: { firstAdminGroupId }, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const permissions = { + connection: { + connectionId: connections.firstId, + accessLevel: AccessLevelEnum.edit, + }, + group: { + groupId: firstAdminGroupId, + accessLevel: AccessLevelEnum.none, + }, + tables: [ + { + tableName: firstTableInfo.testTableName, + accessLevel: { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: false, + }, + }, + ], + }; + + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${firstAdminGroupId}`) + .send({ permissions }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createOrUpdatePermissionRO = JSON.parse(createOrUpdatePermissionResponse.text); + t.is(createOrUpdatePermissionResponse.status, 403); + t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + } +}); + //****************************** TABLE CONTROLLER TESTS ******************************// -currentTest = "GET /connection/tables/:slug"; +currentTest = 'GET /connection/tables/:slug'; -test.serial( - `${currentTest} should return all tables in connection`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesInConnection = await request(app.getHttpServer()) - .get(`/connection/tables/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesInConnection.status, 200); - const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); - t.is(getTablesInConnectionRO.length > 0, true); - const tableIndex = getTablesInConnectionRO.findIndex( - (table: any) => - table.tableName === testData.firstTableInfo.testTableName, - ); - t.is( - getTablesInConnectionRO[tableIndex].table, - testData.firstTableInfo.testTableName, - ); - t.is(typeof getTablesInConnectionRO[tableIndex].permissions, "object"); - const { - visibility, - readonly, - add, - delete: del, - edit, - } = getTablesInConnectionRO[0].permissions; - t.is(visibility, tablePermissions.visibility); - t.is(readonly, tablePermissions.readonly); - t.is(del, tablePermissions.delete); - t.is(edit, tablePermissions.edit); - t.is(add, tablePermissions.add); - } catch (e) { - console.error(e); - } - }, -); +test.serial(`${currentTest} should return all tables in connection`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesInConnection = await request(app.getHttpServer()) + .get(`/connection/tables/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesInConnection.status, 200); + const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); + t.is(getTablesInConnectionRO.length > 0, true); + const tableIndex = getTablesInConnectionRO.findIndex( + (table: any) => table.tableName === testData.firstTableInfo.testTableName, + ); + t.is(getTablesInConnectionRO[tableIndex].table, testData.firstTableInfo.testTableName); + t.is(typeof getTablesInConnectionRO[tableIndex].permissions, 'object'); + const { visibility, readonly, add, delete: del, edit } = getTablesInConnectionRO[0].permissions; + t.is(visibility, tablePermissions.visibility); + t.is(readonly, tablePermissions.readonly); + t.is(del, tablePermissions.delete); + t.is(edit, tablePermissions.edit); + t.is(add, tablePermissions.add); + } catch (e) { + console.error(e); + } +}); -test.serial( - `${currentTest} should throw an exception, when connection id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesInConnection = await request(app.getHttpServer()) - .get(`/connection/tables/`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesInConnection.status, 404); - } catch (e) { - console.error(e); - } - }, -); +test.serial(`${currentTest} should throw an exception, when connection id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesInConnection = await request(app.getHttpServer()) + .get(`/connection/tables/`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesInConnection.status, 404); + } catch (e) { + console.error(e); + } +}); test.serial( `${currentTest} should throw an exception, when connection id passed in request is incorrect`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -1809,9 +1564,9 @@ test.serial( const fakeConnectionId = faker.string.uuid(); const getTablesInConnection = await request(app.getHttpServer()) .get(`/connection/tables/${fakeConnectionId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getTablesInConnection.status, 400); const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); t.is(getTablesInConnectionRO.message, Messages.CONNECTION_NOT_FOUND); @@ -1821,14 +1576,11 @@ test.serial( }, ); -currentTest = "GET /table/rows/:slug"; +currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return found rows from table`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -1838,26 +1590,17 @@ test.serial(`${currentTest} should return found rows from table`, async (t) => { users: { adminUserToken, simpleUserToken }, } = testData; const getTableRows = await request(app.getHttpServer()) - .get( - `/table/rows/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/table/rows/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getTableRows.status, 200); const getTableRowsRO = JSON.parse(getTableRows.text); - const { - rows, - primaryColumns, - pagination, - sortable_by, - structure, - foreignKeys, - } = getTableRowsRO; + const { rows, primaryColumns, pagination, sortable_by, structure, foreignKeys } = getTableRowsRO; t.is(rows.length, Constants.DEFAULT_PAGINATION.perPage); t.is(primaryColumns.length, 1); - t.is(primaryColumns[0].column_name, "id"); - t.is(primaryColumns[0].data_type, "integer"); + t.is(primaryColumns[0].column_name, 'id'); + t.is(primaryColumns[0].data_type, 'integer'); t.is(sortable_by.length, 0); t.is(structure.length, 5); t.is(foreignKeys.length, 0); @@ -1866,106 +1609,189 @@ test.serial(`${currentTest} should return found rows from table`, async (t) => { } }); -test.serial( - `${currentTest} should throw an exception when connection id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesRows = await request(app.getHttpServer()) - .get(`/table/rows/?tableName=${firstTableInfo.testTableName}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesRows.status, 404); - } catch (e) { - console.error(e); - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesRows = await request(app.getHttpServer()) + .get(`/table/rows/?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesRows.status, 404); + } catch (e) { + console.error(e); + } +}); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrec`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeId = faker.string.uuid(); - const getTableRows = await request(app.getHttpServer()) - .get( - `/table/rows/${fakeId}?tableName=${testData.firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTableRows.status, 403); - const getTablesInConnectionRO = JSON.parse(getTableRows.text); - t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrec`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeId = faker.string.uuid(); + const getTableRows = await request(app.getHttpServer()) + .get(`/table/rows/${fakeId}?tableName=${testData.firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRows.status, 403); + const getTablesInConnectionRO = JSON.parse(getTableRows.text); + t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTablesRows = await request(app.getHttpServer()) - .get(`/table/rows/${connections.firstId}?tableName=${fakeTableName}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesRows.status, 403); - const getTablesInConnectionRO = JSON.parse(getTablesRows.text); - t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - } - }, -); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTablesRows = await request(app.getHttpServer()) + .get(`/table/rows/${connections.firstId}?tableName=${fakeTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesRows.status, 403); + const getTablesInConnectionRO = JSON.parse(getTablesRows.text); + t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + } +}); + +currentTest = 'GET /table/structure/:slug'; + +test.serial(`${currentTest} should return table structure`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const getTableStructureRO = JSON.parse(getTablesStructure.text); + + t.is(getTablesStructure.status, 200); + const { structure, primaryColumns, foreignKeys, readonly_fields, table_widgets } = getTableStructureRO; + t.is(structure.length, 5); + t.is(primaryColumns.length, 1); + t.is(primaryColumns[0].column_name, 'id'); + t.is(primaryColumns[0].data_type, 'integer'); + t.is(readonly_fields.length, 0); + t.is(table_widgets.length, 0); + t.is(foreignKeys.length, 0); + } catch (e) { + console.error(e); + } +}); + +test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 404); + } catch (e) { + console.error(e); + } +}); + +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const fakeConnectionId = faker.string.uuid(); + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 403); + const getTablesStructureRO = JSON.parse(getTablesStructure.text); + t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + } +}); -currentTest = "GET /table/structure/:slug"; +test.serial(`${currentTest} should throw an exception when table name not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${connections.firstId}?tableName=`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 400); + const getTablesStructureRO = JSON.parse(getTablesStructure.text); + t.is(getTablesStructureRO.message, Messages.TABLE_NAME_MISSING); + } catch (e) { + console.error(e); + } +}); -test.serial(`${currentTest} should return table structure`, async (t) => { +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -1974,170 +1800,25 @@ test.serial(`${currentTest} should return table structure`, async (t) => { secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; + const fakeTableName = `${faker.lorem.words(1)}_${faker.number.int({ min: 1, max: 10000 })}`; const getTablesStructure = await request(app.getHttpServer()) - .get( - `/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - const getTableStructureRO = JSON.parse(getTablesStructure.text); - - t.is(getTablesStructure.status, 200); - const { - structure, - primaryColumns, - foreignKeys, - readonly_fields, - table_widgets, - } = getTableStructureRO; - t.is(structure.length, 5); - t.is(primaryColumns.length, 1); - t.is(primaryColumns[0].column_name, "id"); - t.is(primaryColumns[0].data_type, "integer"); - t.is(readonly_fields.length, 0); - t.is(table_widgets.length, 0); - t.is(foreignKeys.length, 0); + .get(`/table/structure/${connections.firstId}?tableName=${fakeTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 403); + const getTablesStructureRO = JSON.parse(getTablesStructure.text); + t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); } }); -test.serial( - `${currentTest} should throw an exception when connection id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const getTablesStructure = await request(app.getHttpServer()) - .get(`/table/structure/?tableName=${firstTableInfo.testTableName}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 404); - } catch (e) { - console.error(e); - } - }, -); - -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const fakeConnectionId = faker.string.uuid(); - const getTablesStructure = await request(app.getHttpServer()) - .get( - `/table/structure/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 403); - const getTablesStructureRO = JSON.parse(getTablesStructure.text); - t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - } - }, -); - -test.serial( - `${currentTest} should throw an exception when table name not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesStructure = await request(app.getHttpServer()) - .get(`/table/structure/${connections.firstId}?tableName=`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 400); - const getTablesStructureRO = JSON.parse(getTablesStructure.text); - t.is(getTablesStructureRO.message, Messages.TABLE_NAME_MISSING); - } catch (e) { - console.error(e); - } - }, -); - -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.number.int({ min: 1, max: 10000 })}`; - const getTablesStructure = await request(app.getHttpServer()) - .get( - `/table/structure/${connections.firstId}?tableName=${fakeTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 403); - const getTablesStructureRO = JSON.parse(getTablesStructure.text); - t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - } - }, -); - -currentTest = "POST /table/row/:slug"; +currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should return added row`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -2153,214 +1834,107 @@ test.serial(`${currentTest} should return added row`, async (t) => { const created_at = new Date(); const updated_at = new Date(); const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) + .post(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) .send({ [firstTableInfo.testTableColumnName]: randomName, [firstTableInfo.testTableSecondColumnName]: randomEmail, created_at: created_at, updated_at: updated_at, }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const addRowInTableRO = JSON.parse(addRowInTable.text); t.is(addRowInTable.status, 201); - t.is(Object.hasOwn(addRowInTableRO.row, "id"), true); + t.is(Object.hasOwn(addRowInTableRO.row, 'id'), true); t.is(addRowInTableRO.row[firstTableInfo.testTableColumnName], randomName); - t.is( - addRowInTableRO.row[firstTableInfo.testTableSecondColumnName], - randomEmail, - ); - t.is(Object.hasOwn(addRowInTableRO.row, "created_at"), true); - t.is(Object.hasOwn(addRowInTableRO.row, "updated_at"), true); - t.is(Object.hasOwn(addRowInTableRO, "structure"), true); - t.is(Object.hasOwn(addRowInTableRO, "foreignKeys"), true); - t.is(Object.hasOwn(addRowInTableRO, "primaryColumns"), true); - t.is(Object.hasOwn(addRowInTableRO, "readonly_fields"), true); + t.is(addRowInTableRO.row[firstTableInfo.testTableSecondColumnName], randomEmail); + t.is(Object.hasOwn(addRowInTableRO.row, 'created_at'), true); + t.is(Object.hasOwn(addRowInTableRO.row, 'updated_at'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); } catch (e) { console.error(e); } }); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const fakeConnectionId = faker.string.uuid(); - const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`, - ) - .send({ - [firstTableInfo.testTableColumnName]: randomName, - [firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeConnectionId = faker.string.uuid(); + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`) + .send({ + [firstTableInfo.testTableColumnName]: randomName, + [firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const fakeTableName = `${faker.lorem.words(1)}_${faker.number.int({ min: 1, max: 10000 })}`; - const addRowInTable = await request(app.getHttpServer()) - .post(`/table/row/${connections.firstId}?tableName=${fakeTableName}`) - .send({ - [firstTableInfo.testTableColumnName]: randomName, - [firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - } - }, -); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeTableName = `${faker.lorem.words(1)}_${faker.number.int({ min: 1, max: 10000 })}`; + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${connections.firstId}?tableName=${fakeTableName}`) + .send({ + [firstTableInfo.testTableColumnName]: randomName, + [firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + } +}); -currentTest = "PUT /table/row/:slug"; +currentTest = 'PUT /table/row/:slug'; test.serial( `${currentTest} should throw an exception do not have permission, when you do not have edit permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const updateRowInTable = await request(app.getHttpServer()) - .put( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=2`, - ) - .send({ - name: randomName, - email: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(updateRowInTable.text); - t.is(updateRowInTable.status, 403); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - } - }, -); - -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const fakeConnectionId = faker.string.uuid(); - const addRowInTable = await request(app.getHttpServer()) - .put( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`, - ) - .send({ - name: randomName, - email: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - } - }, -); - -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -2369,25 +1943,24 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; + const randomName = faker.person.firstName(); const randomEmail = faker.internet.email(); const created_at = new Date(); const updated_at = new Date(); - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTable = await request(app.getHttpServer()) - .put( - `/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`, - ) + const updateRowInTable = await request(app.getHttpServer()) + .put(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=2`) .send({ name: randomName, email: randomEmail, created_at: created_at, updated_at: updated_at, }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(updateRowInTable.text); + t.is(updateRowInTable.status, 403); t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); @@ -2395,14 +1968,79 @@ test.serial( }, ); -currentTest = "DELETE /table/row/:slug"; +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeConnectionId = faker.string.uuid(); + const addRowInTable = await request(app.getHttpServer()) + .put(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`) + .send({ + name: randomName, + email: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + } +}); + +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTable = await request(app.getHttpServer()) + .put(`/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`) + .send({ + name: randomName, + email: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + } +}); + +currentTest = 'DELETE /table/row/:slug'; test.serial(`${currentTest} should return delete result`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -2412,12 +2050,10 @@ test.serial(`${currentTest} should return delete result`, async (t) => { users: { adminUserToken, simpleUserToken }, } = testData; const deleteRowInTable = await request(app.getHttpServer()) - .delete( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=19`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .delete(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=19`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(deleteRowInTable.status, 200); } catch (e) { @@ -2425,79 +2061,60 @@ test.serial(`${currentTest} should return delete result`, async (t) => { } }); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeConnectionId = faker.string.uuid(); - const deleteRowInTable = await request(app.getHttpServer()) - .delete( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteRowInTableRO = JSON.parse(deleteRowInTable.text); - t.is(deleteRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - t.is(deleteRowInTable.status, 403); - } catch (e) { - console.error(e); - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeConnectionId = faker.string.uuid(); + const deleteRowInTable = await request(app.getHttpServer()) + .delete(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteRowInTableRO = JSON.parse(deleteRowInTable.text); + t.is(deleteRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + t.is(deleteRowInTable.status, 403); + } catch (e) { + console.error(e); + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTable = await request(app.getHttpServer()) - .delete( - `/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteRowInTabbleRO = JSON.parse(deleteRowInTable.text); - t.is(deleteRowInTabbleRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - } - }, -); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTable = await request(app.getHttpServer()) + .delete(`/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteRowInTabbleRO = JSON.parse(deleteRowInTable.text); + t.is(deleteRowInTabbleRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + } +}); -currentTest = "GET /table/row/:slug"; +currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} should return row`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -2507,163 +2124,131 @@ test.serial(`${currentTest} should return row`, async (t) => { users: { adminUserToken, simpleUserToken }, } = testData; const getRowInTable = await request(app.getHttpServer()) - .get( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=7`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=7`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getRowInTableRO = JSON.parse(getRowInTable.text); t.is(getRowInTable.status, 200); t.is(getRowInTableRO.row.id, 7); - t.is(Object.hasOwn(getRowInTableRO.row, "created_at"), true); - t.is(Object.hasOwn(getRowInTableRO.row, "updated_at"), true); - t.is(Object.hasOwn(getRowInTableRO, "structure"), true); - t.is(Object.hasOwn(getRowInTableRO, "foreignKeys"), true); - t.is(Object.hasOwn(getRowInTableRO, "primaryColumns"), true); - t.is(Object.hasOwn(getRowInTableRO, "readonly_fields"), true); + t.is(Object.hasOwn(getRowInTableRO.row, 'created_at'), true); + t.is(Object.hasOwn(getRowInTableRO.row, 'updated_at'), true); + t.is(Object.hasOwn(getRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(getRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(getRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getRowInTableRO, 'readonly_fields'), true); } catch (e) { console.error(e); } }); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeConnectionId = faker.string.uuid(); - const addRowInTable = await request(app.getHttpServer()) - .get( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=5`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeConnectionId = faker.string.uuid(); + const addRowInTable = await request(app.getHttpServer()) + .get(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=5`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTable = await request(app.getHttpServer()) - .get( - `/table/row/${connections.firstId}?tableName=${fakeTableName}&id=5`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - } - }, -); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTable = await request(app.getHttpServer()) + .get(`/table/row/${connections.firstId}?tableName=${fakeTableName}&id=5`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + } +}); //****************************** TABLE LOGS CONTROLLER TESTS ******************************// -currentTest = "GET /logs/:slug"; - -test.serial( - `${currentTest} should return all found logs in connection'`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .send({ - [firstTableInfo.testTableColumnName]: randomName, - [firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(addRowInTable.status, 201); +currentTest = 'GET /logs/:slug'; - const getTableLogs = await request(app.getHttpServer()) - .get(`/logs/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getRowInTableRO = JSON.parse(getTableLogs.text); +test.serial(`${currentTest} should return all found logs in connection'`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .send({ + [firstTableInfo.testTableColumnName]: randomName, + [firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTable.status, 201); - t.is(getRowInTableRO.logs.length, 1); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "table_name"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "received_data"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "old_data"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "cognitoUserName"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "email"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "operationType"), true); - t.is( - Object.hasOwn(getRowInTableRO.logs[0], "operationStatusResult"), - true, - ); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "createdAt"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "connection_id"), true); - } catch (e) { - console.error(e); - } - }, -); + const getTableLogs = await request(app.getHttpServer()) + .get(`/logs/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getRowInTableRO = JSON.parse(getTableLogs.text); + + t.is(getRowInTableRO.logs.length, 1); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'table_name'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'received_data'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'old_data'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'cognitoUserName'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'email'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'operationType'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'operationStatusResult'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'createdAt'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'connection_id'), true); + } catch (e) { + console.error(e); + } +}); test.serial( `${currentTest} should not return all found logs in connection, when table audit is disabled in connection'`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -2677,52 +2262,46 @@ test.serial( const created_at = new Date(); const updated_at = new Date(); - const updateConnection = - mockFactory.generateConnectionToTestPostgresDBInDocker(); + const updateConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); const updateConnectionResponse = await request(app.getHttpServer()) .put(`/connection/${connections.firstId}`) .send(updateConnection) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(updateConnectionResponse.status, 200); - const newConnectionProperties = - mockFactory.generateConnectionPropertiesUserExcluded(null, false); + const newConnectionProperties = mockFactory.generateConnectionPropertiesUserExcluded(null, false); - const createConnectionPropertiesResponse = await request( - app.getHttpServer(), - ) + const createConnectionPropertiesResponse = await request(app.getHttpServer()) .post(`/connection/properties/${connections.firstId}`) .send(newConnectionProperties) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createConnectionPropertiesResponse.status, 201); const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) + .post(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) .send({ [firstTableInfo.testTableColumnName]: randomName, [firstTableInfo.testTableSecondColumnName]: randomEmail, created_at: created_at, updated_at: updated_at, }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(addRowInTable.status, 201); const getTableLogs = await request(app.getHttpServer()) .get(`/logs/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getRowInTableRO = JSON.parse(getTableLogs.text); t.is(getRowInTableRO.logs.length, 0); @@ -2735,14 +2314,11 @@ test.serial( //****************************** TABLE SETTINGS CONTROLLER TESTS ******************************// -currentTest = "GET /settings/"; +currentTest = 'GET /settings/'; test.skip(`${currentTest} should return empty table settings when it was not created`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -2752,12 +2328,10 @@ test.skip(`${currentTest} should return empty table settings when it was not cre users: { adminUserToken, simpleUserToken }, } = testData; const getTableSettings = await request(app.getHttpServer()) - .get( - `/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getTableSettingsRO = JSON.parse(getTableSettings.text); t.is(getTableSettings.status, 200); t.is(JSON.stringify(getTableSettingsRO), JSON.stringify({})); @@ -2766,75 +2340,65 @@ test.skip(`${currentTest} should return empty table settings when it was not cre } }); -test.serial( - `${currentTest} 'should return table settings when it was created`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} 'should return table settings when it was created`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - ['id'], - [firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + ['id'], + [firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); - const getTableSettings = await request(app.getHttpServer()) - .get(`/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) - .set('Cookie', simpleUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const getTableSettingsRO = JSON.parse(getTableSettings.text); - t.is(getTableSettings.status, 200); - t.is(getTableSettingsRO.hasOwnProperty('id'), true); - t.is(getTableSettingsRO.table_name, createTableSettingsDTO.table_name); - t.is(getTableSettingsRO.display_name, createTableSettingsDTO.display_name); - t.is(JSON.stringify(getTableSettingsRO.search_fields), JSON.stringify(createTableSettingsDTO.search_fields)); - t.is(JSON.stringify(getTableSettingsRO.excluded_fields), JSON.stringify(createTableSettingsDTO.excluded_fields)); - t.is(JSON.stringify(getTableSettingsRO.identification_fields), JSON.stringify([])); - t.is(JSON.stringify(getTableSettingsRO.readonly_fields), JSON.stringify(createTableSettingsDTO.readonly_fields)); - t.is(JSON.stringify(getTableSettingsRO.sortable_by), JSON.stringify(createTableSettingsDTO.sortable_by)); - t.is(JSON.stringify(getTableSettingsRO.autocomplete_columns), JSON.stringify([])); - t.is(getTableSettingsRO.connection_id, connections.firstId); - } catch (e) { - console.error(e); - } + const getTableSettings = await request(app.getHttpServer()) + .get(`/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getTableSettingsRO = JSON.parse(getTableSettings.text); + t.is(getTableSettings.status, 200); + t.is(getTableSettingsRO.hasOwnProperty('id'), true); + t.is(getTableSettingsRO.table_name, createTableSettingsDTO.table_name); + t.is(getTableSettingsRO.display_name, createTableSettingsDTO.display_name); + t.is(JSON.stringify(getTableSettingsRO.search_fields), JSON.stringify(createTableSettingsDTO.search_fields)); + t.is(JSON.stringify(getTableSettingsRO.excluded_fields), JSON.stringify(createTableSettingsDTO.excluded_fields)); + t.is(JSON.stringify(getTableSettingsRO.identification_fields), JSON.stringify([])); + t.is(JSON.stringify(getTableSettingsRO.readonly_fields), JSON.stringify(createTableSettingsDTO.readonly_fields)); + t.is(JSON.stringify(getTableSettingsRO.sortable_by), JSON.stringify(createTableSettingsDTO.sortable_by)); + t.is(JSON.stringify(getTableSettingsRO.autocomplete_columns), JSON.stringify([])); + t.is(getTableSettingsRO.connection_id, connections.firstId); + } catch (e) { + console.error(e); + } }); test.serial( `${currentTest} should throw an exception when you try get settings in connection where you do not have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -2844,36 +2408,32 @@ test.serial( users: { adminUserToken, simpleUserToken }, } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createTableSettingsResponse.status, 201); const getTableSettings = await request(app.getHttpServer()) - .get( - `/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getTableSettingsRO = JSON.parse(getTableSettings.text); t.is(getTableSettings.status, 403); t.is(getTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); @@ -2883,16 +2443,50 @@ test.serial( }, ); -currentTest = "POST /settings/"; +currentTest = 'POST /settings/'; + +test.serial(`${currentTest} should throw an exception do not have permission`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + 'users', + ['id'], + ['email'], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`) + .send(createTableSettingsDTO) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 403); + t.is(JSON.parse(createTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + } +}); test.serial( - `${currentTest} should throw an exception do not have permission`, + `${currentTest} should throw an exception when you try create settings in connection where you do not have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -2902,45 +2496,97 @@ test.serial( users: { adminUserToken, simpleUserToken }, } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - 'users', - ['id'], - ['email'], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`, - ) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}`) .send(createTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createTableSettingsResponse.status, 403); - t.is( - JSON.parse(createTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + + const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); + t.is(createTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); } }, ); +currentTest = 'PUT /settings/'; + +test.serial(`${currentTest} should throw an exception do not have permission`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + ['id'], + [firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const updateTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + [firstTableInfo.testTableSecondColumnName], + ['id'], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); + + const updateTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`) + .send(updateTableSettingsDTO) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(updateTableSettingsResponse.status, 403); + t.is(JSON.parse(updateTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + } +}); + test.serial( - `${currentTest} should throw an exception when you try create settings in connection where you do not have permission`, + `${currentTest} should throw an exception when you try update settings in connection where you do not have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -2949,270 +2595,137 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 403); - - const createTableSettingsRO = JSON.parse( - createTableSettingsResponse.text, + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, ); - t.is(createTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - } - }, -); - -currentTest = "PUT /settings/"; - -test.serial(`${currentTest} should throw an exception do not have permission`, async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - ['id'], - [firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createTableSettingsResponse.status, 201); - const updateTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - [firstTableInfo.testTableSecondColumnName], - ['id'], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const updateTableSettingsResponse = await request(app.getHttpServer()) - .put( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`, - ) - .send(updateTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(updateTableSettingsResponse.status, 403); - t.is( - JSON.parse(updateTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, + const updateTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + [firstTableInfo.testTableSecondColumnName], + ['id'], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, ); - } catch (e) { - console.error(e); - } - }, -); - -test.serial( - `${currentTest} should throw an exception when you try update settings in connection where you do not have permission`, - async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); - - const updateTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - [firstTableInfo.testTableSecondColumnName], - ['id'], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); const updateTableSettingsResponse = await request(app.getHttpServer()) - .put( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}}`, - ) + .put(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}}`) .send(updateTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(updateTableSettingsResponse.status, 403); - t.is( - JSON.parse(updateTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + t.is(JSON.parse(updateTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); } }, ); -currentTest = "DELETE /settings/"; +currentTest = 'DELETE /settings/'; test.serial(`${currentTest} should return array without deleted table settings`, async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - ['id'], - [firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); - - const deleteTableSettingsResponse = await request(app.getHttpServer()) - .delete( - `/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + ['id'], + [firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); - t.is(deleteTableSettingsResponse.status, 403); - t.is( - JSON.parse(deleteTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); - } catch (e) { - console.error(e); - } - }, -); + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const deleteTableSettingsResponse = await request(app.getHttpServer()) + .delete(`/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteTableSettingsResponse.status, 403); + t.is(JSON.parse(deleteTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + } +}); test.serial( - `${currentTest} should throw an exception when you try delete settings in connection where you do not have permission`, - async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + `${currentTest} should throw an exception when you try delete settings in connection where you do not have permission`, + async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createTableSettingsResponse.status, 201); const deleteTableSettingsResponse = await request(app.getHttpServer()) - .delete( - `/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteTableSettingsRO = JSON.parse( - deleteTableSettingsResponse.text, - ); + .delete(`/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteTableSettingsRO = JSON.parse(deleteTableSettingsResponse.text); t.is(deleteTableSettingsResponse.status, 403); t.is(deleteTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { @@ -3223,135 +2736,99 @@ test.serial( //****************************** TABLE WIDGETS CONTROLLER TESTS ******************************// -currentTest = "GET /widgets/:slug"; - -test.serial( - `${currentTest} should return empty widgets array when widgets not created`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTableWidgets = await request(app.getHttpServer()) - .get( - `/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(getTableWidgets.status, 200); - t.is(typeof getTableWidgetsRO, "object"); - t.is(getTableWidgetsRO.length, 0); - } catch (e) { - console.error(e); - } - }, -); +currentTest = 'GET /widgets/:slug'; -test.serial( - `${currentTest} should return array of table widgets for table`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should return empty widgets array when widgets not created`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(getTableWidgets.status, 200); + t.is(typeof getTableWidgetsRO, 'object'); + t.is(getTableWidgetsRO.length, 0); + } catch (e) { + console.error(e); + } +}); - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); - const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", adminUserToken) - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 201); - t.is(typeof createTableWidgetRO, "object"); - t.is(createTableWidgetRO.length, 2); - t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); - t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); - t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); +test.serial(`${currentTest} should return array of table widgets for table`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const getTableWidgets = await request(app.getHttpServer()) - .get( - `/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - t.is(getTableWidgets.status, 200); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(typeof getTableWidgetsRO, "object"); - t.is(getTableWidgetsRO.length, 2); - - t.is(getTableWidgetsRO[0].field_name, newTableWidgets[0].field_name); - t.is(getTableWidgetsRO[1].widget_type, newTableWidgets[1].widget_type); - t.is(compareTableWidgetsArrays(getTableWidgetsRO, newTableWidgets), true); - - const getTableStructureResponse = await request(app.getHttpServer()) - .get( - `/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - t.is(getTableStructureResponse.status, 200); - const getTableStructureRO = JSON.parse(getTableStructureResponse.text); - t.is(Object.hasOwn(getTableStructureRO, "table_widgets"), true); - t.is(getTableStructureRO.table_widgets.length, 2); - t.is( - getTableStructureRO.table_widgets[0].field_name, - newTableWidgets[0].field_name, - ); - t.is( - getTableStructureRO.table_widgets[1].widget_type, - newTableWidgets[1].widget_type, - ); - t.is( - compareTableWidgetsArrays( - getTableStructureRO.table_widgets, - newTableWidgets, - ), - true, - ); - } catch (e) { - console.error(e); - } - }, -); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', adminUserToken) + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 201); + t.is(typeof createTableWidgetRO, 'object'); + t.is(createTableWidgetRO.length, 2); + t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); + t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); + t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); + + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + t.is(getTableWidgets.status, 200); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(typeof getTableWidgetsRO, 'object'); + t.is(getTableWidgetsRO.length, 2); + + t.is(getTableWidgetsRO[0].field_name, newTableWidgets[0].field_name); + t.is(getTableWidgetsRO[1].widget_type, newTableWidgets[1].widget_type); + t.is(compareTableWidgetsArrays(getTableWidgetsRO, newTableWidgets), true); + + const getTableStructureResponse = await request(app.getHttpServer()) + .get(`/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + t.is(getTableStructureResponse.status, 200); + const getTableStructureRO = JSON.parse(getTableStructureResponse.text); + t.is(Object.hasOwn(getTableStructureRO, 'table_widgets'), true); + t.is(getTableStructureRO.table_widgets.length, 2); + t.is(getTableStructureRO.table_widgets[0].field_name, newTableWidgets[0].field_name); + t.is(getTableStructureRO.table_widgets[1].widget_type, newTableWidgets[1].widget_type); + t.is(compareTableWidgetsArrays(getTableStructureRO.table_widgets, newTableWidgets), true); + } catch (e) { + console.error(e); + } +}); test.serial( `${currentTest} should throw an exception, when you try to get widgets from connection, when you do not have permissions`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -3360,31 +2837,26 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) + .post(`/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", adminUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', adminUserToken) + .set('Accept', 'application/json'); const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 201); - t.is(typeof createTableWidgetRO, "object"); + t.is(typeof createTableWidgetRO, 'object'); t.is(createTableWidgetRO.length, 2); const getTableWidgets = await request(app.getHttpServer()) - .get( - `/widgets/${connections.secondId}?tableName=${secondTableInfo.testTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .get(`/widgets/${connections.secondId}?tableName=${secondTableInfo.testTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); const getTableWidgetsRO = JSON.parse(getTableWidgets.text); t.is(getTableWidgets.status, 403); t.is(getTableWidgetsRO.message, Messages.DONT_HAVE_PERMISSIONS); @@ -3394,56 +2866,44 @@ test.serial( }, ); -currentTest = "POST /widget/:slug"; +currentTest = 'POST /widget/:slug'; -test.serial( - `${currentTest} should throw an exception do not have permissions`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw an exception do not have permissions`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); - const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}}`, - ) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 403); - t.is(createTableWidgetRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - } - }, -); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 403); + t.is(createTableWidgetRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + } +}); test.serial( `${currentTest} should throw an exception, when you try add widget in connection, when you do not have permissions`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions(app); const { connections, firstTableInfo, @@ -3452,20 +2912,17 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.secondId}?tableName=${secondTableInfo.testTableName}`, - ) + .post(`/widget/${connections.secondId}?tableName=${secondTableInfo.testTableName}`) .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 403); t.is(createTableWidgetRO.message, Messages.DONT_HAVE_PERMISSIONS); diff --git a/backend/test/ava-tests/saas-tests/user-sign-in-audit.e2e.test.ts b/backend/test/ava-tests/saas-tests/user-sign-in-audit.e2e.test.ts index bb66190d1..db54a0ac2 100644 --- a/backend/test/ava-tests/saas-tests/user-sign-in-audit.e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/user-sign-in-audit.e2e.test.ts @@ -27,498 +27,498 @@ let _testUtils: TestUtils; const _mockFactory = new MockFactory(); async function getCompanyIdByToken(app: INestApplication, token: string): Promise { - const getCompanyResult = await request(app.getHttpServer()) - .get('/company/my/full') - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const companyInfo = JSON.parse(getCompanyResult.text); - return companyInfo.id; + const getCompanyResult = await request(app.getHttpServer()) + .get('/company/my/full') + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const companyInfo = JSON.parse(getCompanyResult.text); + return companyInfo.id; } test.before(async () => { - const moduleFixture = await Test.createTestingModule({ - imports: [ApplicationModule, DatabaseModule], - providers: [DatabaseService, TestUtils], - }).compile(); - app = moduleFixture.createNestApplication(); - _testUtils = moduleFixture.get(TestUtils); - - app.use(cookieParser()); - app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); - app.useGlobalPipes( - new ValidationPipe({ - exceptionFactory(validationErrors: ValidationError[] = []) { - return new ValidationException(validationErrors); - }, - }), - ); - await app.init(); - app.getHttpServer().listen(0); + const moduleFixture = await Test.createTestingModule({ + imports: [ApplicationModule, DatabaseModule], + providers: [DatabaseService, TestUtils], + }).compile(); + app = moduleFixture.createNestApplication(); + _testUtils = moduleFixture.get(TestUtils); + + app.use(cookieParser()); + app.useGlobalFilters(new AllExceptionsFilter(app.get(WinstonLogger))); + app.useGlobalPipes( + new ValidationPipe({ + exceptionFactory(validationErrors: ValidationError[] = []) { + return new ValidationException(validationErrors); + }, + }), + ); + await app.init(); + app.getHttpServer().listen(0); }); test.after(async () => { - try { - await Cacher.clearAllCache(); - await app.close(); - } catch (e) { - console.error('After tests error ' + e); - } + try { + await Cacher.clearAllCache(); + await app.close(); + } catch (e) { + console.error('After tests error ' + e); + } }); currentTest = 'GET /sign-in-audit/logs'; test.serial(`${currentTest} should return sign-in audit logs after successful login`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email, password } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Login again to create a sign-in audit record - const loginUserResult = await request(app.getHttpServer()) - .post('/user/login/') - .send({ email, password }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(loginUserResult.status, 201); - - // Get sign-in audit logs - const getAuditLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getAuditLogsResult.status, 200); - const auditLogsRO = JSON.parse(getAuditLogsResult.text); - - t.is(Object.hasOwn(auditLogsRO, 'logs'), true); - t.is(Object.hasOwn(auditLogsRO, 'pagination'), true); - t.true(auditLogsRO.logs.length >= 1); - - // Check that the log entry has expected structure - const logEntry = auditLogsRO.logs.find((log: any) => log.email === email.toLowerCase()); - t.truthy(logEntry); - t.is(logEntry.status, SignInStatusEnum.SUCCESS); - t.is(logEntry.signInMethod, SignInMethodEnum.EMAIL); - t.is(Object.hasOwn(logEntry, 'createdAt'), true); - t.is(Object.hasOwn(logEntry, 'ipAddress'), true); - } catch (err) { - console.error(err); - throw err; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email, password } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Login again to create a sign-in audit record + const loginUserResult = await request(app.getHttpServer()) + .post('/user/login/') + .send({ email, password }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(loginUserResult.status, 201); + + // Get sign-in audit logs + const getAuditLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getAuditLogsResult.status, 200); + const auditLogsRO = JSON.parse(getAuditLogsResult.text); + + t.is(Object.hasOwn(auditLogsRO, 'logs'), true); + t.is(Object.hasOwn(auditLogsRO, 'pagination'), true); + t.true(auditLogsRO.logs.length >= 1); + + // Check that the log entry has expected structure + const logEntry = auditLogsRO.logs.find((log: any) => log.email === email.toLowerCase()); + t.truthy(logEntry); + t.is(logEntry.status, SignInStatusEnum.SUCCESS); + t.is(logEntry.signInMethod, SignInMethodEnum.EMAIL); + t.is(Object.hasOwn(logEntry, 'createdAt'), true); + t.is(Object.hasOwn(logEntry, 'ipAddress'), true); + } catch (err) { + console.error(err); + throw err; + } }); test.serial(`${currentTest} should return sign-in audit logs with failed login attempt`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email, password } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Attempt login with wrong password to create a failed sign-in audit record - const wrongPassword = 'wrong_password_12345'; - const failedLoginResult = await request(app.getHttpServer()) - .post('/user/login/') - .send({ email, password: wrongPassword }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(failedLoginResult.status, 400); - - // Get sign-in audit logs - const getAuditLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getAuditLogsResult.status, 200); - const auditLogsRO = JSON.parse(getAuditLogsResult.text); - - t.is(Object.hasOwn(auditLogsRO, 'logs'), true); - t.true(auditLogsRO.logs.length >= 1); - - // Find the failed login entry - const failedLogEntry = auditLogsRO.logs.find( - (log: any) => log.email === email.toLowerCase() && log.status === SignInStatusEnum.FAILED, - ); - t.truthy(failedLogEntry); - t.is(failedLogEntry.signInMethod, SignInMethodEnum.EMAIL); - t.truthy(failedLogEntry.failureReason); - } catch (err) { - console.error(err); - throw err; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email, password } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Attempt login with wrong password to create a failed sign-in audit record + const wrongPassword = 'wrong_password_12345'; + const failedLoginResult = await request(app.getHttpServer()) + .post('/user/login/') + .send({ email, password: wrongPassword }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(failedLoginResult.status, 400); + + // Get sign-in audit logs + const getAuditLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getAuditLogsResult.status, 200); + const auditLogsRO = JSON.parse(getAuditLogsResult.text); + + t.is(Object.hasOwn(auditLogsRO, 'logs'), true); + t.true(auditLogsRO.logs.length >= 1); + + // Find the failed login entry + const failedLogEntry = auditLogsRO.logs.find( + (log: any) => log.email === email.toLowerCase() && log.status === SignInStatusEnum.FAILED, + ); + t.truthy(failedLogEntry); + t.is(failedLogEntry.signInMethod, SignInMethodEnum.EMAIL); + t.truthy(failedLogEntry.failureReason); + } catch (err) { + console.error(err); + throw err; + } }); test.serial(`${currentTest} should filter sign-in audit logs by status`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email, password } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Create a failed login attempt - const wrongPassword = 'wrong_password_12345'; - await request(app.getHttpServer()) - .post('/user/login/') - .send({ email, password: wrongPassword }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - // Create a successful login - await request(app.getHttpServer()) - .post('/user/login/') - .send({ email, password }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - // Get only failed sign-in audit logs - const getFailedLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}&status=${SignInStatusEnum.FAILED}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getFailedLogsResult.status, 200); - const failedLogsRO = JSON.parse(getFailedLogsResult.text); - - t.is(Object.hasOwn(failedLogsRO, 'logs'), true); - // All returned logs should have failed status - failedLogsRO.logs.forEach((log: any) => { - t.is(log.status, SignInStatusEnum.FAILED); - }); - - // Get only successful sign-in audit logs - const getSuccessLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}&status=${SignInStatusEnum.SUCCESS}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getSuccessLogsResult.status, 200); - const successLogsRO = JSON.parse(getSuccessLogsResult.text); - - t.is(Object.hasOwn(successLogsRO, 'logs'), true); - // All returned logs should have success status - successLogsRO.logs.forEach((log: any) => { - t.is(log.status, SignInStatusEnum.SUCCESS); - }); - } catch (err) { - console.error(err); - throw err; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email, password } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Create a failed login attempt + const wrongPassword = 'wrong_password_12345'; + await request(app.getHttpServer()) + .post('/user/login/') + .send({ email, password: wrongPassword }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + // Create a successful login + await request(app.getHttpServer()) + .post('/user/login/') + .send({ email, password }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + // Get only failed sign-in audit logs + const getFailedLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}&status=${SignInStatusEnum.FAILED}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getFailedLogsResult.status, 200); + const failedLogsRO = JSON.parse(getFailedLogsResult.text); + + t.is(Object.hasOwn(failedLogsRO, 'logs'), true); + // All returned logs should have failed status + failedLogsRO.logs.forEach((log: any) => { + t.is(log.status, SignInStatusEnum.FAILED); + }); + + // Get only successful sign-in audit logs + const getSuccessLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}&status=${SignInStatusEnum.SUCCESS}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getSuccessLogsResult.status, 200); + const successLogsRO = JSON.parse(getSuccessLogsResult.text); + + t.is(Object.hasOwn(successLogsRO, 'logs'), true); + // All returned logs should have success status + successLogsRO.logs.forEach((log: any) => { + t.is(log.status, SignInStatusEnum.SUCCESS); + }); + } catch (err) { + console.error(err); + throw err; + } }); test.serial(`${currentTest} should filter sign-in audit logs by email`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email, password } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Create a successful login - await request(app.getHttpServer()) - .post('/user/login/') - .send({ email, password }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - // Get sign-in audit logs filtered by email - const getAuditLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}&email=${email.toLowerCase()}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getAuditLogsResult.status, 200); - const auditLogsRO = JSON.parse(getAuditLogsResult.text); - - t.is(Object.hasOwn(auditLogsRO, 'logs'), true); - // All returned logs should have the searched email - auditLogsRO.logs.forEach((log: any) => { - t.is(log.email, email.toLowerCase()); - }); - } catch (err) { - console.error(err); - throw err; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email, password } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Create a successful login + await request(app.getHttpServer()) + .post('/user/login/') + .send({ email, password }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + // Get sign-in audit logs filtered by email + const getAuditLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}&email=${email.toLowerCase()}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getAuditLogsResult.status, 200); + const auditLogsRO = JSON.parse(getAuditLogsResult.text); + + t.is(Object.hasOwn(auditLogsRO, 'logs'), true); + // All returned logs should have the searched email + auditLogsRO.logs.forEach((log: any) => { + t.is(log.email, email.toLowerCase()); + }); + } catch (err) { + console.error(err); + throw err; + } }); test.serial(`${currentTest} should filter sign-in audit logs by sign-in method`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email, password } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Create a successful login - await request(app.getHttpServer()) - .post('/user/login/') - .send({ email, password }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - // Get sign-in audit logs filtered by email sign-in method - const getAuditLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}&signInMethod=${SignInMethodEnum.EMAIL}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getAuditLogsResult.status, 200); - const auditLogsRO = JSON.parse(getAuditLogsResult.text); - - t.is(Object.hasOwn(auditLogsRO, 'logs'), true); - // All returned logs should have email sign-in method - auditLogsRO.logs.forEach((log: any) => { - t.is(log.signInMethod, SignInMethodEnum.EMAIL); - }); - } catch (err) { - console.error(err); - throw err; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email, password } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Create a successful login + await request(app.getHttpServer()) + .post('/user/login/') + .send({ email, password }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + // Get sign-in audit logs filtered by email sign-in method + const getAuditLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}&signInMethod=${SignInMethodEnum.EMAIL}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getAuditLogsResult.status, 200); + const auditLogsRO = JSON.parse(getAuditLogsResult.text); + + t.is(Object.hasOwn(auditLogsRO, 'logs'), true); + // All returned logs should have email sign-in method + auditLogsRO.logs.forEach((log: any) => { + t.is(log.signInMethod, SignInMethodEnum.EMAIL); + }); + } catch (err) { + console.error(err); + throw err; + } }); test.serial(`${currentTest} should support pagination for sign-in audit logs`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email, password } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Create multiple login attempts - for (let i = 0; i < 5; i++) { - await request(app.getHttpServer()) - .post('/user/login/') - .send({ email, password }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - } - - // Get sign-in audit logs with pagination - const getAuditLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}&page=1&perPage=2`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getAuditLogsResult.status, 200); - const auditLogsRO = JSON.parse(getAuditLogsResult.text); - - t.is(Object.hasOwn(auditLogsRO, 'logs'), true); - t.is(Object.hasOwn(auditLogsRO, 'pagination'), true); - t.true(auditLogsRO.logs.length <= 2); - t.is(Object.hasOwn(auditLogsRO.pagination, 'total'), true); - t.is(Object.hasOwn(auditLogsRO.pagination, 'lastPage'), true); - t.is(Object.hasOwn(auditLogsRO.pagination, 'perPage'), true); - t.is(Object.hasOwn(auditLogsRO.pagination, 'currentPage'), true); - } catch (err) { - console.error(err); - throw err; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email, password } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Create multiple login attempts + for (let i = 0; i < 5; i++) { + await request(app.getHttpServer()) + .post('/user/login/') + .send({ email, password }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + } + + // Get sign-in audit logs with pagination + const getAuditLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}&page=1&perPage=2`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getAuditLogsResult.status, 200); + const auditLogsRO = JSON.parse(getAuditLogsResult.text); + + t.is(Object.hasOwn(auditLogsRO, 'logs'), true); + t.is(Object.hasOwn(auditLogsRO, 'pagination'), true); + t.true(auditLogsRO.logs.length <= 2); + t.is(Object.hasOwn(auditLogsRO.pagination, 'total'), true); + t.is(Object.hasOwn(auditLogsRO.pagination, 'lastPage'), true); + t.is(Object.hasOwn(auditLogsRO.pagination, 'perPage'), true); + t.is(Object.hasOwn(auditLogsRO.pagination, 'currentPage'), true); + } catch (err) { + console.error(err); + throw err; + } }); test.serial(`${currentTest} should return 400 for invalid status filter`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Get sign-in audit logs with invalid status - const getAuditLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}&status=invalid_status`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getAuditLogsResult.status, 400); - const errorRO = JSON.parse(getAuditLogsResult.text); - t.is(errorRO.message, Messages.INVALID_SIGN_IN_STATUS); - } catch (err) { - console.error(err); - throw err; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Get sign-in audit logs with invalid status + const getAuditLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}&status=invalid_status`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getAuditLogsResult.status, 400); + const errorRO = JSON.parse(getAuditLogsResult.text); + t.is(errorRO.message, Messages.INVALID_SIGN_IN_STATUS); + } catch (err) { + console.error(err); + throw err; + } }); test.serial(`${currentTest} should return 400 for invalid sign-in method filter`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Get sign-in audit logs with invalid sign-in method - const getAuditLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}&signInMethod=invalid_method`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getAuditLogsResult.status, 400); - const errorRO = JSON.parse(getAuditLogsResult.text); - t.is(errorRO.message, Messages.INVALID_SIGN_IN_METHOD); - } catch (err) { - console.error(err); - throw err; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Get sign-in audit logs with invalid sign-in method + const getAuditLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}&signInMethod=invalid_method`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getAuditLogsResult.status, 400); + const errorRO = JSON.parse(getAuditLogsResult.text); + t.is(errorRO.message, Messages.INVALID_SIGN_IN_METHOD); + } catch (err) { + console.error(err); + throw err; + } }); test.serial(`${currentTest} should filter sign-in audit logs by date range`, async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email, password } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Create a successful login - await request(app.getHttpServer()) - .post('/user/login/') - .send({ email, password }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const today = new Date(); - const yesterday = new Date(today); - yesterday.setDate(yesterday.getDate() - 1); - const tomorrow = new Date(today); - tomorrow.setDate(tomorrow.getDate() + 1); - - const dateFrom = yesterday.toISOString(); - const dateTo = tomorrow.toISOString(); - - // Get sign-in audit logs filtered by date range - const getAuditLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}&dateFrom=${dateFrom}&dateTo=${dateTo}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getAuditLogsResult.status, 200); - const auditLogsRO = JSON.parse(getAuditLogsResult.text); - - t.is(Object.hasOwn(auditLogsRO, 'logs'), true); - t.true(auditLogsRO.logs.length >= 1); - } catch (err) { - console.error(err); - throw err; - } + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email, password } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Create a successful login + await request(app.getHttpServer()) + .post('/user/login/') + .send({ email, password }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const today = new Date(); + const yesterday = new Date(today); + yesterday.setDate(yesterday.getDate() - 1); + const tomorrow = new Date(today); + tomorrow.setDate(tomorrow.getDate() + 1); + + const dateFrom = yesterday.toISOString(); + const dateTo = tomorrow.toISOString(); + + // Get sign-in audit logs filtered by date range + const getAuditLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}&dateFrom=${dateFrom}&dateTo=${dateTo}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getAuditLogsResult.status, 200); + const auditLogsRO = JSON.parse(getAuditLogsResult.text); + + t.is(Object.hasOwn(auditLogsRO, 'logs'), true); + t.true(auditLogsRO.logs.length >= 1); + } catch (err) { + console.error(err); + throw err; + } }); test.serial(`${currentTest} should not return logs from another company`, async (t) => { - try { - // Register first user - const firstUserInfo = await registerUserAndReturnUserInfo(app); - const { token: firstToken, email: firstEmail, password: firstPassword } = firstUserInfo; - - // Get first user's company ID - const firstCompanyId = await getCompanyIdByToken(app, firstToken); - - // Register second user (different company) - const secondUserInfo = await registerUserAndReturnUserInfo(app); - const { token: secondToken, email: secondEmail, password: secondPassword } = secondUserInfo; - - // Get second user's company ID - const secondCompanyId = await getCompanyIdByToken(app, secondToken); - - // Create login for first user - await request(app.getHttpServer()) - .post('/user/login/') - .send({ email: firstEmail, password: firstPassword }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - // Create login for second user - await request(app.getHttpServer()) - .post('/user/login/') - .send({ email: secondEmail, password: secondPassword }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - // Get sign-in audit logs for first company - const getFirstCompanyLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${firstCompanyId}`) - .set('Cookie', firstToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getFirstCompanyLogsResult.status, 200); - const firstCompanyLogsRO = JSON.parse(getFirstCompanyLogsResult.text); - - // First company logs should not contain second user's email - const secondUserLogInFirstCompany = firstCompanyLogsRO.logs.find( - (log: any) => log.email === secondEmail.toLowerCase(), - ); - t.falsy(secondUserLogInFirstCompany); - - // Get sign-in audit logs for second company - const getSecondCompanyLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${secondCompanyId}`) - .set('Cookie', secondToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getSecondCompanyLogsResult.status, 200); - const secondCompanyLogsRO = JSON.parse(getSecondCompanyLogsResult.text); - - // Second company logs should not contain first user's email - const firstUserLogInSecondCompany = secondCompanyLogsRO.logs.find( - (log: any) => log.email === firstEmail.toLowerCase(), - ); - t.falsy(firstUserLogInSecondCompany); - } catch (err) { - console.error(err); - throw err; - } + try { + // Register first user + const firstUserInfo = await registerUserAndReturnUserInfo(app); + const { token: firstToken, email: firstEmail, password: firstPassword } = firstUserInfo; + + // Get first user's company ID + const firstCompanyId = await getCompanyIdByToken(app, firstToken); + + // Register second user (different company) + const secondUserInfo = await registerUserAndReturnUserInfo(app); + const { token: secondToken, email: secondEmail, password: secondPassword } = secondUserInfo; + + // Get second user's company ID + const secondCompanyId = await getCompanyIdByToken(app, secondToken); + + // Create login for first user + await request(app.getHttpServer()) + .post('/user/login/') + .send({ email: firstEmail, password: firstPassword }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + // Create login for second user + await request(app.getHttpServer()) + .post('/user/login/') + .send({ email: secondEmail, password: secondPassword }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + // Get sign-in audit logs for first company + const getFirstCompanyLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${firstCompanyId}`) + .set('Cookie', firstToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getFirstCompanyLogsResult.status, 200); + const firstCompanyLogsRO = JSON.parse(getFirstCompanyLogsResult.text); + + // First company logs should not contain second user's email + const secondUserLogInFirstCompany = firstCompanyLogsRO.logs.find( + (log: any) => log.email === secondEmail.toLowerCase(), + ); + t.falsy(secondUserLogInFirstCompany); + + // Get sign-in audit logs for second company + const getSecondCompanyLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${secondCompanyId}`) + .set('Cookie', secondToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getSecondCompanyLogsResult.status, 200); + const secondCompanyLogsRO = JSON.parse(getSecondCompanyLogsResult.text); + + // Second company logs should not contain first user's email + const firstUserLogInSecondCompany = secondCompanyLogsRO.logs.find( + (log: any) => log.email === firstEmail.toLowerCase(), + ); + t.falsy(firstUserLogInSecondCompany); + } catch (err) { + console.error(err); + throw err; + } }); test.serial( - `${currentTest} should not show audit for login attempt with non-existent user in company logs`, - async (t) => { - try { - const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); - const { token, email } = adminUserRegisterInfo; - - // Get company ID by token - const companyId = await getCompanyIdByToken(app, token); - - // Attempt login with non-existent email - const nonExistentEmail = `nonexistent_${faker.string.uuid()}@example.com`; - const failedLoginResult = await request(app.getHttpServer()) - .post('/user/login/') - .send({ email: nonExistentEmail, password: 'any_password', companyId }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - t.is(failedLoginResult.status, 404); - - // Get sign-in audit logs - const getAuditLogsResult = await request(app.getHttpServer()) - .get(`/sign-in-audit/logs?companyId=${companyId}`) - .set('Cookie', token) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - t.is(getAuditLogsResult.status, 200); - const auditLogsRO = JSON.parse(getAuditLogsResult.text); - - // Non-existent user login attempts should NOT be visible in company logs - // because the user doesn't belong to the company - const failedLogEntry = auditLogsRO.logs.find((log: any) => log.email === nonExistentEmail.toLowerCase()); - t.falsy(failedLogEntry); - } catch (err) { - console.error(err); - throw err; - } - }, + `${currentTest} should not show audit for login attempt with non-existent user in company logs`, + async (t) => { + try { + const adminUserRegisterInfo = await registerUserAndReturnUserInfo(app); + const { token, email } = adminUserRegisterInfo; + + // Get company ID by token + const companyId = await getCompanyIdByToken(app, token); + + // Attempt login with non-existent email + const nonExistentEmail = `nonexistent_${faker.string.uuid()}@example.com`; + const failedLoginResult = await request(app.getHttpServer()) + .post('/user/login/') + .send({ email: nonExistentEmail, password: 'any_password', companyId }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(failedLoginResult.status, 404); + + // Get sign-in audit logs + const getAuditLogsResult = await request(app.getHttpServer()) + .get(`/sign-in-audit/logs?companyId=${companyId}`) + .set('Cookie', token) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getAuditLogsResult.status, 200); + const auditLogsRO = JSON.parse(getAuditLogsResult.text); + + // Non-existent user login attempts should NOT be visible in company logs + // because the user doesn't belong to the company + const failedLogEntry = auditLogsRO.logs.find((log: any) => log.email === nonExistentEmail.toLowerCase()); + t.falsy(failedLogEntry); + } catch (err) { + console.error(err); + throw err; + } + }, ); diff --git a/backend/test/ava-tests/saas-tests/user-table-different-group-connection-readonly-permissions-e2e.test.ts b/backend/test/ava-tests/saas-tests/user-table-different-group-connection-readonly-permissions-e2e.test.ts index 1540aa9fa..c6537696e 100644 --- a/backend/test/ava-tests/saas-tests/user-table-different-group-connection-readonly-permissions-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/user-table-different-group-connection-readonly-permissions-e2e.test.ts @@ -1,38 +1,34 @@ /* eslint-disable security/detect-object-injection */ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { faker } from "@faker-js/faker"; -import { INestApplication, ValidationPipe } from "@nestjs/common"; -import { Test } from "@nestjs/testing"; -import test from "ava"; -import { ValidationError } from "class-validator"; -import cookieParser from "cookie-parser"; -import request from "supertest"; -import { ApplicationModule } from "../../../src/app.module.js"; -import { WinstonLogger } from "../../../src/entities/logging/winston-logger.js"; -import { - AccessLevelEnum, - QueryOrderingEnum, -} from "../../../src/enums/index.js"; -import { AllExceptionsFilter } from "../../../src/exceptions/all-exceptions.filter.js"; -import { ValidationException } from "../../../src/exceptions/custom-exceptions/validation-exception.js"; -import { Messages } from "../../../src/exceptions/text/messages.js"; -import { Cacher } from "../../../src/helpers/cache/cacher.js"; -import { Constants } from "../../../src/helpers/constants/constants.js"; -import { DatabaseModule } from "../../../src/shared/database/database.module.js"; -import { DatabaseService } from "../../../src/shared/database/database.service.js"; -import { MockFactory } from "../../mock.factory.js"; -import { compareTableWidgetsArrays } from "../../utils/compare-table-widgets-arrays.js"; -import { inviteUserInCompanyAndAcceptInvitation } from "../../utils/register-user-and-return-user-info.js"; -import { TestUtils } from "../../utils/test.utils.js"; -import { createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions } from "../../utils/user-with-different-permissions-utils.js"; +import { faker } from '@faker-js/faker'; +import { INestApplication, ValidationPipe } from '@nestjs/common'; +import { Test } from '@nestjs/testing'; +import test from 'ava'; +import { ValidationError } from 'class-validator'; +import cookieParser from 'cookie-parser'; +import request from 'supertest'; +import { ApplicationModule } from '../../../src/app.module.js'; +import { WinstonLogger } from '../../../src/entities/logging/winston-logger.js'; +import { AccessLevelEnum, QueryOrderingEnum } from '../../../src/enums/index.js'; +import { AllExceptionsFilter } from '../../../src/exceptions/all-exceptions.filter.js'; +import { ValidationException } from '../../../src/exceptions/custom-exceptions/validation-exception.js'; +import { Messages } from '../../../src/exceptions/text/messages.js'; +import { Cacher } from '../../../src/helpers/cache/cacher.js'; +import { Constants } from '../../../src/helpers/constants/constants.js'; +import { DatabaseModule } from '../../../src/shared/database/database.module.js'; +import { DatabaseService } from '../../../src/shared/database/database.service.js'; +import { MockFactory } from '../../mock.factory.js'; +import { compareTableWidgetsArrays } from '../../utils/compare-table-widgets-arrays.js'; +import { inviteUserInCompanyAndAcceptInvitation } from '../../utils/register-user-and-return-user-info.js'; +import { TestUtils } from '../../utils/test.utils.js'; +import { createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions } from '../../utils/user-with-different-permissions-utils.js'; let app: INestApplication; let _testUtils: TestUtils; let currentTest: string; const mockFactory = new MockFactory(); -const newConnectionToPostgres = - mockFactory.generateConnectionToTestPostgresDBInDocker(); +const newConnectionToPostgres = mockFactory.generateConnectionToTestPostgresDBInDocker(); const updateConnection = mockFactory.generateUpdateConnectionDto(); const newGroup1 = mockFactory.generateCreateGroupDto1(); const tablePermissions = { @@ -69,81 +65,70 @@ test.after(async () => { await Cacher.clearAllCache(); await app.close(); } catch (e) { - console.error("After tests error " + e); + console.error('After tests error ' + e); } }); //***************************************** USER NOT ADDED INTO ADMIN GROUP //****************************** CONNECTION CONTROLLER -currentTest = "GET /connections/"; +currentTest = 'GET /connections/'; -test.serial( - `${currentTest} should return connections, where second user have access`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const findAll = await request(app.getHttpServer()) - .get("/connections") - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - - t.is(findAll.status, 200); - - t.is(findAll.status, 200); - - const result = findAll.body.connections; - const nonTestConnection = result.find( - ({ connection }) => connection.id === connections.firstId, - ); - t.is(result.length, 5); - t.is(Object.hasOwn(nonTestConnection, "connection"), true); - t.is(Object.hasOwn(nonTestConnection, "accessLevel"), true); - t.is(nonTestConnection.accessLevel, AccessLevelEnum.readonly); - - t.is(Object.hasOwn(nonTestConnection.connection, "host"), true); - t.is(Object.hasOwn(result[0].connection, "host"), true); - t.is(typeof result[0].connection.port, "number"); - t.is(Object.hasOwn(result[0].connection, "port"), true); - t.is(Object.hasOwn(result[0].connection, "username"), true); - t.is(Object.hasOwn(result[0].connection, "database"), true); - t.is(Object.hasOwn(result[0].connection, "sid"), true); - t.is(Object.hasOwn(result[0].connection, "createdAt"), true); - t.is(Object.hasOwn(result[0].connection, "updatedAt"), true); - t.is(Object.hasOwn(result[0].connection, "password"), false); - t.is(Object.hasOwn(result[0].connection, "groups"), false); - t.is(Object.hasOwn(result[0].connection, "author"), false); - const testConnectionsCount = result.filter( - (el: any) => el.connection.isTestConnection, - ).length; - t.is(testConnectionsCount, 4); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should return connections, where second user have access`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const findAll = await request(app.getHttpServer()) + .get('/connections') + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + + t.is(findAll.status, 200); + + t.is(findAll.status, 200); + + const result = findAll.body.connections; + const nonTestConnection = result.find(({ connection }) => connection.id === connections.firstId); + t.is(result.length, 5); + t.is(Object.hasOwn(nonTestConnection, 'connection'), true); + t.is(Object.hasOwn(nonTestConnection, 'accessLevel'), true); + t.is(nonTestConnection.accessLevel, AccessLevelEnum.readonly); + + t.is(Object.hasOwn(nonTestConnection.connection, 'host'), true); + t.is(Object.hasOwn(result[0].connection, 'host'), true); + t.is(typeof result[0].connection.port, 'number'); + t.is(Object.hasOwn(result[0].connection, 'port'), true); + t.is(Object.hasOwn(result[0].connection, 'username'), true); + t.is(Object.hasOwn(result[0].connection, 'database'), true); + t.is(Object.hasOwn(result[0].connection, 'sid'), true); + t.is(Object.hasOwn(result[0].connection, 'createdAt'), true); + t.is(Object.hasOwn(result[0].connection, 'updatedAt'), true); + t.is(Object.hasOwn(result[0].connection, 'password'), false); + t.is(Object.hasOwn(result[0].connection, 'groups'), false); + t.is(Object.hasOwn(result[0].connection, 'author'), false); + const testConnectionsCount = result.filter((el: any) => el.connection.isTestConnection).length; + t.is(testConnectionsCount, 4); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "GET /connection/one/:slug"; +currentTest = 'GET /connection/one/:slug'; test.serial(`${currentTest} should return a found connection`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -156,26 +141,26 @@ test.serial(`${currentTest} should return a found connection`, async (t) => { const searchedConnectionId = connections.firstId; const findOneResponce = await request(app.getHttpServer()) .get(`/connection/one/${searchedConnectionId}`) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); t.is(findOneResponce.status, 200); const result = findOneResponce.body.connection; t.is(result.title, newConnectionToPostgres.title); - t.is(result.type, "postgres"); + t.is(result.type, 'postgres'); t.is(result.host, newConnectionToPostgres.host); - t.is(typeof result.port, "number"); + t.is(typeof result.port, 'number'); t.is(result.port, newConnectionToPostgres.port); - t.is(result.username, "postgres"); + t.is(result.username, 'postgres'); t.is(result.database, newConnectionToPostgres.database); t.is(result.sid, null); - t.is(Object.hasOwn(result, "createdAt"), true); - t.is(Object.hasOwn(result, "updatedAt"), true); - t.is(Object.hasOwn(result, "password"), false); - t.is(Object.hasOwn(result, "groups"), false); - t.is(Object.hasOwn(result, "author"), false); + t.is(Object.hasOwn(result, 'createdAt'), true); + t.is(Object.hasOwn(result, 'updatedAt'), true); + t.is(Object.hasOwn(result, 'password'), false); + t.is(Object.hasOwn(result, 'groups'), false); + t.is(Object.hasOwn(result, 'author'), false); } catch (e) { console.error(e); throw e; @@ -187,9 +172,7 @@ test.serial( async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -203,14 +186,14 @@ test.serial( const findOneResponce = await request(app.getHttpServer()) .get(`/connection/one/${searchedConnectionId}`) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); // todo add checking connection object properties t.is(findOneResponce.status, 200); const findOneRO = JSON.parse(findOneResponce.text); - t.is(Object.hasOwn(findOneRO, "host"), false); + t.is(Object.hasOwn(findOneRO, 'host'), false); } catch (e) { console.error(e); throw e; @@ -218,52 +201,42 @@ test.serial( }, ); -currentTest = "PUT /connection"; +currentTest = 'PUT /connection'; -test.serial( - `${currentTest} should throw exception you do not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw exception you do not have permission`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const updateConnectionResponse = await request(app.getHttpServer()) - .put(`/connection/${connections.firstId}`) - .send(updateConnection) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const updateConnectionResponse = await request(app.getHttpServer()) + .put(`/connection/${connections.firstId}`) + .send(updateConnection) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(updateConnectionResponse.status, 403); - t.is( - JSON.parse(updateConnectionResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(updateConnectionResponse.status, 403); + t.is(JSON.parse(updateConnectionResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should return throw an exception, when you try update a connection without permissions in it`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -275,15 +248,12 @@ test.serial( const updateConnectionResponse = await request(app.getHttpServer()) .put(`/connection/${connections.secondId}`) .send(updateConnection) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(updateConnectionResponse.status, 403); - t.is( - JSON.parse(updateConnectionResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + t.is(JSON.parse(updateConnectionResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -291,57 +261,50 @@ test.serial( }, ); -currentTest = "DELETE /connection/:slug"; - -test.serial( - `${currentTest} should throw an exception do not have permissions`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +currentTest = 'DELETE /connection/:slug'; - const response = await request(app.getHttpServer()) - .put(`/connection/delete/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(response.status, 403); - t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); +test.serial(`${currentTest} should throw an exception do not have permissions`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - //deleted connection found in database - const findOneResponce = await request(app.getHttpServer()) - .get(`/connection/one/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const response = await request(app.getHttpServer()) + .put(`/connection/delete/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(response.status, 403); + t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); + + //deleted connection found in database + const findOneResponce = await request(app.getHttpServer()) + .get(`/connection/one/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(findOneResponce.status, 200); - t.is(JSON.parse(findOneResponce.text).connection.id, connections.firstId); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(findOneResponce.status, 200); + t.is(JSON.parse(findOneResponce.text).connection.id, connections.firstId); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception, when you try to delete connection without permission`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -353,18 +316,18 @@ test.serial( const response = await request(app.getHttpServer()) .put(`/connection/delete/${connections.secondId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 403); t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); //connection wasn't deleted const findOneResponce = await request(app.getHttpServer()) .get(`/connection/one/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(findOneResponce.status, 200); } catch (e) { @@ -374,52 +337,42 @@ test.serial( }, ); -currentTest = "POST /connection/group/:slug"; +currentTest = 'POST /connection/group/:slug'; -test.serial( - `${currentTest} should throw an exception don not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw an exception don not have permission`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 403); - t.is( - JSON.parse(createGroupResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(createGroupResponse.status, 403); + t.is(JSON.parse(createGroupResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception when you try add group in connection without permission in it`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -430,16 +383,13 @@ test.serial( } = testData; const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.secondId}`) - .set("Cookie", simpleUserToken) + .set('Cookie', simpleUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createGroupResponse.status, 403); - t.is( - JSON.parse(createGroupResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + t.is(JSON.parse(createGroupResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -447,69 +397,62 @@ test.serial( }, ); -currentTest = "PUT /connection/group/:slug"; +currentTest = 'PUT /connection/group/:slug'; -test.serial( - `${currentTest} should return connection without deleted group result`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should return connection without deleted group result`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connections.firstId}`) - .set("Cookie", adminUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connections.firstId}`) + .set('Cookie', adminUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - // create group in connection - let result = createGroupResponse.body; - t.is(createGroupResponse.status, 201); + // create group in connection + let result = createGroupResponse.body; + t.is(createGroupResponse.status, 201); - t.is(Object.hasOwn(result, "id"), true); - t.is(result.title, newGroup1.title); + t.is(Object.hasOwn(result, 'id'), true); + t.is(result.title, newGroup1.title); - const createGroupRO = JSON.parse(createGroupResponse.text); + const createGroupRO = JSON.parse(createGroupResponse.text); - const response = await request(app.getHttpServer()) - .put(`/connection/group/delete/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .send({ groupId: createGroupRO.id }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const response = await request(app.getHttpServer()) + .put(`/connection/group/delete/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .send({ groupId: createGroupRO.id }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - //after deleting group - result = response.body; + //after deleting group + result = response.body; - t.is(response.status, 403); - t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(response.status, 403); + t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception, when you try delete group in connection without permissions`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -520,27 +463,27 @@ test.serial( } = testData; const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.secondId}`) - .set("Cookie", adminUserToken) + .set('Cookie', adminUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); // create group in connection const result = createGroupResponse.body; t.is(createGroupResponse.status, 201); - t.is(Object.hasOwn(result, "id"), true); + t.is(Object.hasOwn(result, 'id'), true); t.is(result.title, newGroup1.title); const createGroupRO = JSON.parse(createGroupResponse.text); const response = await request(app.getHttpServer()) .put(`/connection/group/delete/${connections.secondId}`) - .set("Cookie", simpleUserToken) + .set('Cookie', simpleUserToken) .send({ groupId: createGroupRO.id }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 403); t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); @@ -551,14 +494,12 @@ test.serial( }, ); -currentTest = "GET /connection/groups/:slug"; +currentTest = 'GET /connection/groups/:slug'; test.serial(`${currentTest} should groups in connection`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -572,28 +513,28 @@ test.serial(`${currentTest} should groups in connection`, async (t) => { const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.firstId}`) - .set("Cookie", adminUserToken) + .set('Cookie', adminUserToken) .send(newRandomGroup2) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createGroupResponse.status, 201); const response = await request(app.getHttpServer()) .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 200); const result = JSON.parse(response.text); const _groupId = result[0].group.id; - t.is(Object.hasOwn(result[0].group, "title"), true); + t.is(Object.hasOwn(result[0].group, 'title'), true); t.is(result[0].accessLevel, AccessLevelEnum.readonly); const index = result.findIndex((el: any) => { - return el.group.title === "Admin"; + return el.group.title === 'Admin'; }); t.is(index >= 0, false); @@ -608,9 +549,7 @@ test.serial( async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -621,18 +560,18 @@ test.serial( } = testData; const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.secondId}`) - .set("Cookie", adminUserToken) + .set('Cookie', adminUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createGroupResponse.status, 201); const response = await request(app.getHttpServer()) .get(`/connection/groups/${connections.secondId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 200); const result = JSON.parse(response.text); @@ -644,158 +583,129 @@ test.serial( }, ); -currentTest = "GET /connection/permissions"; +currentTest = 'GET /connection/permissions'; -test.serial( - `${currentTest} should return permissions object for current group in current connection`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - const groupId = getGroupsRO[0].group.id; +test.serial(`${currentTest} should return permissions object for current group in current connection`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const groupId = getGroupsRO[0].group.id; - const response = await request(app.getHttpServer()) - .get( - `/connection/permissions?connectionId=${connections.firstId}&groupId=${groupId}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const result = JSON.parse(response.text); - t.is(response.status, 200); + const response = await request(app.getHttpServer()) + .get(`/connection/permissions?connectionId=${connections.firstId}&groupId=${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const result = JSON.parse(response.text); + t.is(response.status, 200); - t.is(Object.hasOwn(result, "connection"), true); - t.is(Object.hasOwn(result, "group"), true); - t.is(Object.hasOwn(result, "tables"), true); - t.is(typeof result.connection, "object"); - t.is(typeof result.group, "object"); - t.is(result.connection.connectionId, connections.firstId); - t.is(result.group.groupId, groupId); - t.is(result.connection.accessLevel, AccessLevelEnum.readonly); - t.is(result.group.accessLevel, AccessLevelEnum.readonly); - t.is(typeof result.tables, "object"); + t.is(Object.hasOwn(result, 'connection'), true); + t.is(Object.hasOwn(result, 'group'), true); + t.is(Object.hasOwn(result, 'tables'), true); + t.is(typeof result.connection, 'object'); + t.is(typeof result.group, 'object'); + t.is(result.connection.connectionId, connections.firstId); + t.is(result.group.groupId, groupId); + t.is(result.connection.accessLevel, AccessLevelEnum.readonly); + t.is(result.group.accessLevel, AccessLevelEnum.readonly); + t.is(typeof result.tables, 'object'); + + const { tables } = result; + const tableIndex = tables.findIndex((table: any) => table.tableName === firstTableInfo.testTableName); + t.is(tables.length > 0, true); + t.is(typeof tables[tableIndex], 'object'); + t.is(Object.hasOwn(tables[tableIndex], 'accessLevel'), true); + t.is(tables[tableIndex].accessLevel.visibility, tablePermissions.visibility); + t.is(tables[tableIndex].accessLevel.readonly, tablePermissions.readonly); + t.is(tables[tableIndex].accessLevel.add, tablePermissions.add); + t.is(tables[tableIndex].accessLevel.delete, tablePermissions.delete); + t.is(tables[tableIndex].accessLevel.edit, tablePermissions.edit); + } catch (e) { + console.error(e); + throw e; + } +}); - const { tables } = result; - const tableIndex = tables.findIndex( - (table: any) => table.tableName === firstTableInfo.testTableName, - ); - t.is(tables.length > 0, true); - t.is(typeof tables[tableIndex], "object"); - t.is(Object.hasOwn(tables[tableIndex], "accessLevel"), true); - t.is( - tables[tableIndex].accessLevel.visibility, - tablePermissions.visibility, - ); - t.is(tables[tableIndex].accessLevel.readonly, tablePermissions.readonly); - t.is(tables[tableIndex].accessLevel.add, tablePermissions.add); - t.is(tables[tableIndex].accessLevel.delete, tablePermissions.delete); - t.is(tables[tableIndex].accessLevel.edit, tablePermissions.edit); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -currentTest = "GET /connection/user/permissions"; - -test.serial( - `${currentTest} should return permissions object for current group in current connection`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +currentTest = 'GET /connection/user/permissions'; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - const groupId = getGroupsRO[0].group.id; +test.serial(`${currentTest} should return permissions object for current group in current connection`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const response = await request(app.getHttpServer()) - .get( - `/connection/user/permissions?connectionId=${connections.firstId}&groupId=${groupId}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(response.status, 200); - const result = JSON.parse(response.text); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const groupId = getGroupsRO[0].group.id; - t.is(Object.hasOwn(result, "connection"), true); - t.is(Object.hasOwn(result, "group"), true); - t.is(Object.hasOwn(result, "tables"), true); - t.is(typeof result.connection, "object"); - t.is(typeof result.group, "object"); - t.is(result.connection.connectionId, connections.firstId); - t.is(result.group.groupId, groupId); - t.is(result.connection.accessLevel, AccessLevelEnum.readonly); - t.is(result.group.accessLevel, AccessLevelEnum.readonly); - t.is(typeof result.tables, "object"); + const response = await request(app.getHttpServer()) + .get(`/connection/user/permissions?connectionId=${connections.firstId}&groupId=${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(response.status, 200); + const result = JSON.parse(response.text); - const { tables } = result; - const foundTableIndex = tables.findIndex( - (table) => table.tableName === firstTableInfo.testTableName, - ); - t.is(tables.length > 0, true); - t.is(typeof tables[foundTableIndex], "object"); - t.is(Object.hasOwn(tables[foundTableIndex], "accessLevel"), true); - t.is( - tables[foundTableIndex].accessLevel.visibility, - tablePermissions.visibility, - ); - t.is( - tables[foundTableIndex].accessLevel.readonly, - tablePermissions.readonly, - ); - t.is(tables[foundTableIndex].accessLevel.add, tablePermissions.add); - t.is(tables[foundTableIndex].accessLevel.delete, tablePermissions.delete); - t.is(tables[foundTableIndex].accessLevel.edit, tablePermissions.edit); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(Object.hasOwn(result, 'connection'), true); + t.is(Object.hasOwn(result, 'group'), true); + t.is(Object.hasOwn(result, 'tables'), true); + t.is(typeof result.connection, 'object'); + t.is(typeof result.group, 'object'); + t.is(result.connection.connectionId, connections.firstId); + t.is(result.group.groupId, groupId); + t.is(result.connection.accessLevel, AccessLevelEnum.readonly); + t.is(result.group.accessLevel, AccessLevelEnum.readonly); + t.is(typeof result.tables, 'object'); + + const { tables } = result; + const foundTableIndex = tables.findIndex((table) => table.tableName === firstTableInfo.testTableName); + t.is(tables.length > 0, true); + t.is(typeof tables[foundTableIndex], 'object'); + t.is(Object.hasOwn(tables[foundTableIndex], 'accessLevel'), true); + t.is(tables[foundTableIndex].accessLevel.visibility, tablePermissions.visibility); + t.is(tables[foundTableIndex].accessLevel.readonly, tablePermissions.readonly); + t.is(tables[foundTableIndex].accessLevel.add, tablePermissions.add); + t.is(tables[foundTableIndex].accessLevel.delete, tablePermissions.delete); + t.is(tables[foundTableIndex].accessLevel.edit, tablePermissions.edit); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should return permissions object for current group in current connection for current user`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -807,35 +717,33 @@ test.serial( const getGroupsResponse = await request(app.getHttpServer()) .get(`/connection/groups/${connections.secondId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); const groupId = getGroupsRO[0].group.id; const response = await request(app.getHttpServer()) - .get( - `/connection/user/permissions?connectionId=${connections.secondId}&groupId=${groupId}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/connection/user/permissions?connectionId=${connections.secondId}&groupId=${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 200); const result = JSON.parse(response.text); - t.is(Object.hasOwn(result, "connection"), true); - t.is(Object.hasOwn(result, "group"), true); - t.is(Object.hasOwn(result, "tables"), true); - t.is(typeof result.connection, "object"); - t.is(typeof result.group, "object"); + t.is(Object.hasOwn(result, 'connection'), true); + t.is(Object.hasOwn(result, 'group'), true); + t.is(Object.hasOwn(result, 'tables'), true); + t.is(typeof result.connection, 'object'); + t.is(typeof result.group, 'object'); t.is(result.connection.connectionId, connections.secondId); t.is(result.group.groupId, groupId); t.is(result.connection.accessLevel, AccessLevelEnum.none); t.is(result.group.accessLevel, AccessLevelEnum.none); - t.is(typeof result.tables, "object"); + t.is(typeof result.tables, 'object'); } catch (e) { console.error(e); throw e; @@ -845,49 +753,42 @@ test.serial( //****************************** GROUP CONTROLLER ******************************// -currentTest = "GET /groups/"; +currentTest = 'GET /groups/'; -test.serial( - `${currentTest} should return found groups with current user`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - users: { simpleUserToken }, - } = testData; +test.serial(`${currentTest} should return found groups with current user`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + users: { simpleUserToken }, + } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/groups/`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - const { groups, groupsCount } = getGroupsRO; - t.is(groupsCount, 1); - t.is(groups.length, 1); - t.is(Object.hasOwn(groups[0], "group"), true); - t.is(Object.hasOwn(groups[0], "accessLevel"), true); - - t.is(Object.hasOwn(groups[0].group, "title"), true); - t.is(Object.hasOwn(groups[0].group, "isMain"), true); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/groups/`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const { groups, groupsCount } = getGroupsRO; + t.is(groupsCount, 1); + t.is(groups.length, 1); + t.is(Object.hasOwn(groups[0], 'group'), true); + t.is(Object.hasOwn(groups[0], 'accessLevel'), true); + + t.is(Object.hasOwn(groups[0].group, 'title'), true); + t.is(Object.hasOwn(groups[0].group, 'isMain'), true); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "GET /group/users/:slug"; +currentTest = 'GET /group/users/:slug'; test.serial(`${currentTest} it should return users in groups`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -898,9 +799,9 @@ test.serial(`${currentTest} it should return users in groups`, async (t) => { } = testData; const getGroupsResponse = await request(app.getHttpServer()) .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); const nonAdminGroupIndex = getGroupsRO.findIndex((element) => { @@ -909,9 +810,9 @@ test.serial(`${currentTest} it should return users in groups`, async (t) => { const groupId = getGroupsRO[nonAdminGroupIndex].group.id; const response = await request(app.getHttpServer()) .get(`/group/users/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 200); const _getUsersRO = JSON.parse(response.text); t.is(getGroupsRO.length, 2); @@ -926,9 +827,7 @@ test.serial( async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -939,9 +838,9 @@ test.serial( } = testData; const getGroupsResponse = await request(app.getHttpServer()) .get(`/connection/groups/${connections.secondId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); @@ -949,9 +848,9 @@ test.serial( const response = await request(app.getHttpServer()) .get(`/group/users/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getUsersRO = JSON.parse(response.text); t.is(getUsersRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { @@ -961,421 +860,432 @@ test.serial( }, ); -currentTest = "PUT /group/user"; - -test.serial( - `${currentTest} should throw exception ${Messages.DONT_HAVE_PERMISSIONS}`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +currentTest = 'PUT /group/user'; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw exception ${Messages.DONT_HAVE_PERMISSIONS}`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const groupId = getGroupsRO[0].group.id; + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const email = faker.internet.email(); - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); - t.is(addUserInGroupResponse.status, 403); - t.is(Object.hasOwn(addUserInGroupRO, "message"), true); - t.is(addUserInGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const groupId = getGroupsRO[0].group.id; + + const email = faker.internet.email(); + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); + t.is(addUserInGroupResponse.status, 403); + t.is(Object.hasOwn(addUserInGroupRO, 'message'), true); + t.is(addUserInGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw exception, when group id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw exception, when group id not passed in request`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const _groupId = getGroupsRO[0].group.id; - const email = faker.internet.email(); - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", simpleUserToken) - .send({ email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); - t.is(addUserInGroupResponse.status, 400); - t.is(addUserInGroupRO.message, Messages.GROUP_ID_MISSING); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const _groupId = getGroupsRO[0].group.id; + const email = faker.internet.email(); + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', simpleUserToken) + .send({ email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); + t.is(addUserInGroupResponse.status, 400); + t.is(addUserInGroupRO.message, Messages.GROUP_ID_MISSING); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw exception, when group id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw exception, when group id passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); - const _getGroupsRO = JSON.parse(getGroupsResponse.text); - - const email = faker.internet.email(); - const groupId = faker.string.uuid(); - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); - t.is(addUserInGroupResponse.status, 400); - t.is(addUserInGroupRO.message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(getGroupsResponse.status, 200); + const _getGroupsRO = JSON.parse(getGroupsResponse.text); + + const email = faker.internet.email(); + const groupId = faker.string.uuid(); + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); + t.is(addUserInGroupResponse.status, 400); + t.is(addUserInGroupRO.message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "DELETE /group/:slug"; +currentTest = 'DELETE /group/:slug'; -test.serial( - `${currentTest} should throw ${Messages.DONT_HAVE_PERMISSIONS} exception`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw ${Messages.DONT_HAVE_PERMISSIONS} exception`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); - const groupId = JSON.parse(getGroupsResponse.text)[0].group.id; - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteGroupRO = JSON.parse(deleteGroupResponse.text); - t.is(deleteGroupResponse.status, 403); - t.is(deleteGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(getGroupsResponse.status, 200); + const groupId = JSON.parse(getGroupsResponse.text)[0].group.id; + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteGroupRO = JSON.parse(deleteGroupResponse.text); + t.is(deleteGroupResponse.status, 403); + t.is(deleteGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when you try delete admin group`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw an exception when you try delete admin group`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const adminGroupIndex = getGroupsRO.findIndex( - (group) => group.group.isMain, - ); + const adminGroupIndex = getGroupsRO.findIndex((group) => group.group.isMain); - const groupId = getGroupsRO[adminGroupIndex].group.id; - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteGroupRO = JSON.parse(deleteGroupResponse.text); - t.is(deleteGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const groupId = getGroupsRO[adminGroupIndex].group.id; + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteGroupRO = JSON.parse(deleteGroupResponse.text); + t.is(deleteGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when group id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw an exception when group id not passed in request`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const _groupId = getGroupsRO[0].group.id; - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(deleteGroupResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const _groupId = getGroupsRO[0].group.id; + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(deleteGroupResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when group id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw an exception when group id passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); + t.is(getGroupsResponse.status, 200); - const groupId = faker.string.uuid(); - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteGroupRO = JSON.parse(deleteGroupResponse.text); - t.is(deleteGroupRO.message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const groupId = faker.string.uuid(); + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteGroupRO = JSON.parse(deleteGroupResponse.text); + t.is(deleteGroupRO.message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "PUT /group/user/delete"; +currentTest = 'PUT /group/user/delete'; -test.serial( - `${currentTest} should throw an exception ${Messages.DONT_HAVE_PERMISSIONS}`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw an exception ${Messages.DONT_HAVE_PERMISSIONS}`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const groupId = getGroupsRO[0].group.id; + const groupId = getGroupsRO[0].group.id; - const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( - testData.users.adminUserToken, - undefined, - app, - undefined, - ); + const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( + testData.users.adminUserToken, + undefined, + app, + undefined, + ); - const email = thirdTestUser.email; - - const deleteUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user/delete") - .set("Cookie", simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(deleteUserInGroupResponse.status, 403); - const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); - t.is(deleteUserInGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const email = thirdTestUser.email; + + const deleteUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user/delete') + .set('Cookie', simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(deleteUserInGroupResponse.status, 403); + const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); + t.is(deleteUserInGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw exception, when group id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw exception, when group id not passed in request`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const _groupId = getGroupsRO[0].group.id; + const _groupId = getGroupsRO[0].group.id; - const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( - testData.users.adminUserToken, - undefined, - app, - undefined, - ); + const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( + testData.users.adminUserToken, + undefined, + app, + undefined, + ); - const email = thirdTestUser.email; - - const deleteUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user/delete") - .set("Cookie", simpleUserToken) - .send({ email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(deleteUserInGroupResponse.status, 400); - const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); - t.is(deleteUserInGroupRO.message, Messages.GROUP_ID_MISSING); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const email = thirdTestUser.email; + + const deleteUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user/delete') + .set('Cookie', simpleUserToken) + .send({ email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(deleteUserInGroupResponse.status, 400); + const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); + t.is(deleteUserInGroupRO.message, Messages.GROUP_ID_MISSING); + } catch (e) { + console.error(e); + throw e; + } +}); //****************************** PERMISSION CONTROLLER TESTS ******************************// -currentTest = "PUT permissions/:slug"; +currentTest = 'PUT permissions/:slug'; + +test.serial(`${currentTest} should throw an exception do not have permission`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connections.firstId}`) + .set('Cookie', adminUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + t.is(createGroupResponse.status, 201); + const newGroupId = createGroupRO.id; + + const permissions = { + connection: { + connectionId: connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: firstTableInfo.testTableName, + accessLevel: { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: false, + }, + }, + ], + }; + + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createOrUpdatePermissionRO = JSON.parse(createOrUpdatePermissionResponse.text); + t.is(createOrUpdatePermissionResponse.status, 403); + t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( - `${currentTest} should throw an exception do not have permission`, + `${currentTest} should throw ${Messages.DONT_HAVE_PERMISSIONS} exception object when you update permissions`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -1383,97 +1293,26 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connections.firstId}`) - .set("Cookie", adminUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - t.is(createGroupResponse.status, 201); - const newGroupId = createGroupRO.id; + + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + + const groupId = getGroupsRO[0].group.id; const permissions = { connection: { + accessLevel: AccessLevelEnum.none, connectionId: connections.firstId, - accessLevel: AccessLevelEnum.readonly, }, group: { - groupId: newGroupId, accessLevel: AccessLevelEnum.readonly, - }, - tables: [ - { - tableName: firstTableInfo.testTableName, - accessLevel: { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: false, - }, - }, - ], - }; - - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createOrUpdatePermissionRO = JSON.parse( - createOrUpdatePermissionResponse.text, - ); - t.is(createOrUpdatePermissionResponse.status, 403); - t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw ${Messages.DONT_HAVE_PERMISSIONS} exception object when you update permissions`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - - const groupId = getGroupsRO[0].group.id; - - const permissions = { - connection: { - accessLevel: AccessLevelEnum.none, - connectionId: connections.firstId, - }, - group: { - accessLevel: AccessLevelEnum.readonly, - groupId: groupId, + groupId: groupId, }, tables: [ { @@ -1489,17 +1328,13 @@ test.serial( ], }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) .put(`/permissions/${groupId}?connectionId=${connections.firstId}`) .send({ permissions }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createOrUpdatePermissionRO = JSON.parse( - createOrUpdatePermissionResponse.text, - ); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createOrUpdatePermissionRO = JSON.parse(createOrUpdatePermissionResponse.text); t.is(createOrUpdatePermissionResponse.status, 403); t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { @@ -1509,157 +1344,127 @@ test.serial( }, ); -test.serial( - `${currentTest} should throw an exception, when you try change admin group`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups: { firstAdminGroupId }, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw an exception, when you try change admin group`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups: { firstAdminGroupId }, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const permissions = { - connection: { - connectionId: connections.firstId, - accessLevel: AccessLevelEnum.edit, - }, - group: { - groupId: firstAdminGroupId, - accessLevel: AccessLevelEnum.none, - }, - tables: [ - { - tableName: firstTableInfo.testTableName, - accessLevel: { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: false, - }, + const permissions = { + connection: { + connectionId: connections.firstId, + accessLevel: AccessLevelEnum.edit, + }, + group: { + groupId: firstAdminGroupId, + accessLevel: AccessLevelEnum.none, + }, + tables: [ + { + tableName: firstTableInfo.testTableName, + accessLevel: { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: false, }, - ], - }; - - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put(`/permissions/${firstAdminGroupId}`) - .send({ permissions }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createOrUpdatePermissionRO = JSON.parse( - createOrUpdatePermissionResponse.text, - ); - t.is(createOrUpdatePermissionResponse.status, 403); - t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + }, + ], + }; + + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${firstAdminGroupId}`) + .send({ permissions }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createOrUpdatePermissionRO = JSON.parse(createOrUpdatePermissionResponse.text); + t.is(createOrUpdatePermissionResponse.status, 403); + t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); //****************************** TABLE CONTROLLER TESTS ******************************// -currentTest = "GET /connection/tables/:slug"; +currentTest = 'GET /connection/tables/:slug'; -test.serial( - `${currentTest} should return all tables in connection`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesInConnection = await request(app.getHttpServer()) - .get(`/connection/tables/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesInConnection.status, 200); - const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); - t.is(getTablesInConnectionRO.length > 0, true); - const tableIndex = getTablesInConnectionRO.findIndex( - (table: any) => table.table === testData.firstTableInfo.testTableName, - ); - t.is( - getTablesInConnectionRO[tableIndex].table, - testData.firstTableInfo.testTableName, - ); - t.is(typeof getTablesInConnectionRO[tableIndex].permissions, "object"); - const { - visibility, - readonly, - add, - delete: del, - edit, - } = getTablesInConnectionRO[0].permissions; - t.is(visibility, tablePermissions.visibility); - t.is(readonly, tablePermissions.readonly); - t.is(del, tablePermissions.delete); - t.is(edit, tablePermissions.edit); - t.is(add, tablePermissions.add); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should return all tables in connection`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesInConnection = await request(app.getHttpServer()) + .get(`/connection/tables/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesInConnection.status, 200); + const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); + t.is(getTablesInConnectionRO.length > 0, true); + const tableIndex = getTablesInConnectionRO.findIndex( + (table: any) => table.table === testData.firstTableInfo.testTableName, + ); + t.is(getTablesInConnectionRO[tableIndex].table, testData.firstTableInfo.testTableName); + t.is(typeof getTablesInConnectionRO[tableIndex].permissions, 'object'); + const { visibility, readonly, add, delete: del, edit } = getTablesInConnectionRO[0].permissions; + t.is(visibility, tablePermissions.visibility); + t.is(readonly, tablePermissions.readonly); + t.is(del, tablePermissions.delete); + t.is(edit, tablePermissions.edit); + t.is(add, tablePermissions.add); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception, when connection id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesInConnection = await request(app.getHttpServer()) - .get(`/connection/tables/`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesInConnection.status, 404); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception, when connection id not passed in request`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesInConnection = await request(app.getHttpServer()) + .get(`/connection/tables/`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesInConnection.status, 404); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception, when connection id passed in request is incorrect`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -1671,9 +1476,9 @@ test.serial( const fakeConnectionId = faker.string.uuid(); const getTablesInConnection = await request(app.getHttpServer()) .get(`/connection/tables/${fakeConnectionId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getTablesInConnection.status, 400); const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); t.is(getTablesInConnectionRO.message, Messages.CONNECTION_NOT_FOUND); @@ -1684,14 +1489,12 @@ test.serial( }, ); -currentTest = "GET /table/rows/:slug"; +currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return found rows from table`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -1701,26 +1504,17 @@ test.serial(`${currentTest} should return found rows from table`, async (t) => { users: { adminUserToken, simpleUserToken }, } = testData; const getTableRows = await request(app.getHttpServer()) - .get( - `/table/rows/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/table/rows/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getTableRows.status, 200); const getTableRowsRO = JSON.parse(getTableRows.text); - const { - rows, - primaryColumns, - pagination, - sortable_by, - structure, - foreignKeys, - } = getTableRowsRO; + const { rows, primaryColumns, pagination, sortable_by, structure, foreignKeys } = getTableRowsRO; t.is(rows.length, Constants.DEFAULT_PAGINATION.perPage); t.is(primaryColumns.length, 1); - t.is(primaryColumns[0].column_name, "id"); - t.is(primaryColumns[0].data_type, "integer"); + t.is(primaryColumns[0].column_name, 'id'); + t.is(primaryColumns[0].data_type, 'integer'); t.is(sortable_by.length, 0); t.is(structure.length, 5); t.is(foreignKeys.length, 0); @@ -1730,109 +1524,10 @@ test.serial(`${currentTest} should return found rows from table`, async (t) => { } }); -test.serial( - `${currentTest} should throw an exception when connection id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesRows = await request(app.getHttpServer()) - .get(`/table/rows/?tableName=${firstTableInfo.testTableName}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesRows.status, 404); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrec`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeId = faker.string.uuid(); - const getTableRows = await request(app.getHttpServer()) - .get( - `/table/rows/${fakeId}?tableName=${testData.firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTableRows.status, 403); - const getTablesInConnectionRO = JSON.parse(getTableRows.text); - t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTablesRows = await request(app.getHttpServer()) - .get(`/table/rows/${connections.firstId}?tableName=${fakeTableName}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesRows.status, 403); - const getTablesInConnectionRO = JSON.parse(getTablesRows.text); - t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -currentTest = "GET /table/structure/:slug"; - -test.serial(`${currentTest} should return table structure`, async (t) => { +test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -1841,175 +1536,221 @@ test.serial(`${currentTest} should return table structure`, async (t) => { secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const getTablesStructure = await request(app.getHttpServer()) - .get( - `/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - const getTableStructureRO = JSON.parse(getTablesStructure.text); - - t.is(getTablesStructure.status, 200); - const { - structure, - primaryColumns, - foreignKeys, - readonly_fields, - table_widgets, - } = getTableStructureRO; - t.is(structure.length, 5); - t.is(primaryColumns.length, 1); - t.is(primaryColumns[0].column_name, "id"); - t.is(primaryColumns[0].data_type, "integer"); - t.is(readonly_fields.length, 0); - t.is(table_widgets.length, 0); - t.is(foreignKeys.length, 0); + const getTablesRows = await request(app.getHttpServer()) + .get(`/table/rows/?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesRows.status, 404); } catch (e) { console.error(e); throw e; } }); -test.serial( - `${currentTest} should throw an exception when connection id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrec`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeId = faker.string.uuid(); + const getTableRows = await request(app.getHttpServer()) + .get(`/table/rows/${fakeId}?tableName=${testData.firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRows.status, 403); + const getTablesInConnectionRO = JSON.parse(getTableRows.text); + t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); - const getTablesStructure = await request(app.getHttpServer()) - .get(`/table/structure/?tableName=${firstTableInfo.testTableName}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 404); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTablesRows = await request(app.getHttpServer()) + .get(`/table/rows/${connections.firstId}?tableName=${fakeTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesRows.status, 403); + const getTablesInConnectionRO = JSON.parse(getTablesRows.text); + t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +currentTest = 'GET /table/structure/:slug'; - const fakeConnectionId = faker.string.uuid(); - const getTablesStructure = await request(app.getHttpServer()) - .get( - `/table/structure/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 403); - const getTablesStructureRO = JSON.parse(getTablesStructure.text); - t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should return table structure`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); -test.serial( - `${currentTest} should throw an exception when table name not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesStructure = await request(app.getHttpServer()) - .get(`/table/structure/${connections.firstId}?tableName=`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 400); - const getTablesStructureRO = JSON.parse(getTablesStructure.text); - t.is(getTablesStructureRO.message, Messages.TABLE_NAME_MISSING); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const getTableStructureRO = JSON.parse(getTablesStructure.text); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTablesStructure = await request(app.getHttpServer()) - .get( - `/table/structure/${connections.firstId}?tableName=${fakeTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 403); - const getTablesStructureRO = JSON.parse(getTablesStructure.text); - t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(getTablesStructure.status, 200); + const { structure, primaryColumns, foreignKeys, readonly_fields, table_widgets } = getTableStructureRO; + t.is(structure.length, 5); + t.is(primaryColumns.length, 1); + t.is(primaryColumns[0].column_name, 'id'); + t.is(primaryColumns[0].data_type, 'integer'); + t.is(readonly_fields.length, 0); + t.is(table_widgets.length, 0); + t.is(foreignKeys.length, 0); + } catch (e) { + console.error(e); + throw e; + } +}); + +test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 404); + } catch (e) { + console.error(e); + throw e; + } +}); + +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const fakeConnectionId = faker.string.uuid(); + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 403); + const getTablesStructureRO = JSON.parse(getTablesStructure.text); + t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); + +test.serial(`${currentTest} should throw an exception when table name not passed in request`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${connections.firstId}?tableName=`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 400); + const getTablesStructureRO = JSON.parse(getTablesStructure.text); + t.is(getTablesStructureRO.message, Messages.TABLE_NAME_MISSING); + } catch (e) { + console.error(e); + throw e; + } +}); + +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${connections.firstId}?tableName=${fakeTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 403); + const getTablesStructureRO = JSON.parse(getTablesStructure.text); + t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "POST /table/row/:slug"; +currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should return added row`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -2025,184 +1766,160 @@ test.serial(`${currentTest} should return added row`, async (t) => { const created_at = new Date(); const updated_at = new Date(); const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) + .post(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) .send({ [firstTableInfo.testTableColumnName]: randomName, [firstTableInfo.testTableSecondColumnName]: randomEmail, created_at: created_at, updated_at: updated_at, }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const addRowInTableRO = JSON.parse(addRowInTable.text); t.is(addRowInTable.status, 201); - t.is(Object.hasOwn(addRowInTableRO.row, "id"), true); + t.is(Object.hasOwn(addRowInTableRO.row, 'id'), true); t.is(addRowInTableRO.row[firstTableInfo.testTableColumnName], randomName); - t.is( - addRowInTableRO.row[firstTableInfo.testTableSecondColumnName], - randomEmail, - ); - t.is(Object.hasOwn(addRowInTableRO.row, "created_at"), true); - t.is(Object.hasOwn(addRowInTableRO.row, "updated_at"), true); - t.is(Object.hasOwn(addRowInTableRO, "structure"), true); - t.is(Object.hasOwn(addRowInTableRO, "foreignKeys"), true); - t.is(Object.hasOwn(addRowInTableRO, "primaryColumns"), true); - t.is(Object.hasOwn(addRowInTableRO, "readonly_fields"), true); + t.is(addRowInTableRO.row[firstTableInfo.testTableSecondColumnName], randomEmail); + t.is(Object.hasOwn(addRowInTableRO.row, 'created_at'), true); + t.is(Object.hasOwn(addRowInTableRO.row, 'updated_at'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); } catch (e) { console.error(e); throw e; } }); -test.serial( - `${currentTest} should throw an exception, when user does not have add permission`, - async (t) => { - try { - const permissionToAdd = { - visibility: true, - readonly: false, - add: false, - delete: false, - edit: false, - }; - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - permissionToAdd, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); +test.serial(`${currentTest} should throw an exception, when user does not have add permission`, async (t) => { + try { + const permissionToAdd = { + visibility: true, + readonly: false, + add: false, + delete: false, + edit: false, + }; + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( + app, + permissionToAdd, + ); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const created_at = new Date(); - const updated_at = new Date(); - const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .send({ - [firstTableInfo.testTableColumnName]: randomName, - [firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const _addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTable.status, 403); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const fakeConnectionId = faker.string.uuid(); - const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`, - ) - .send({ - [firstTableInfo.testTableColumnName]: randomName, - [firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const created_at = new Date(); + const updated_at = new Date(); + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .send({ + [firstTableInfo.testTableColumnName]: randomName, + [firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const _addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTable.status, 403); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTable = await request(app.getHttpServer()) - .post(`/table/row/${connections.firstId}?tableName=${fakeTableName}`) - .send({ - [firstTableInfo.testTableColumnName]: randomName, - [firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeConnectionId = faker.string.uuid(); + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`) + .send({ + [firstTableInfo.testTableColumnName]: randomName, + [firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); + +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${connections.firstId}?tableName=${fakeTableName}`) + .send({ + [firstTableInfo.testTableColumnName]: randomName, + [firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "PUT /table/row/:slug"; +currentTest = 'PUT /table/row/:slug'; test.serial( `${currentTest} should throw an exception do not have permission, when you do not have edit permission`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -2217,18 +1934,16 @@ test.serial( const created_at = new Date(); const updated_at = new Date(); const updateRowInTable = await request(app.getHttpServer()) - .put( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=2`, - ) + .put(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=2`) .send({ name: randomName, email: randomEmail, created_at: created_at, updated_at: updated_at, }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const addRowInTableRO = JSON.parse(updateRowInTable.text); t.is(updateRowInTable.status, 403); t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); @@ -2239,100 +1954,222 @@ test.serial( }, ); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const fakeConnectionId = faker.string.uuid(); - const addRowInTable = await request(app.getHttpServer()) - .put( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`, - ) - .send({ - name: randomName, - email: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeConnectionId = faker.string.uuid(); + const addRowInTable = await request(app.getHttpServer()) + .put(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`) + .send({ + name: randomName, + email: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTable = await request(app.getHttpServer()) - .put( - `/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`, - ) - .send({ - name: randomName, - email: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTable = await request(app.getHttpServer()) + .put(`/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`) + .send({ + name: randomName, + email: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); + +currentTest = 'DELETE /table/row/:slug'; + +test.serial(`${currentTest} should return delete result`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const deleteRowInTable = await request(app.getHttpServer()) + .delete(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=19`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTable.status, 200); + } catch (e) { + console.error(e); + throw e; + } +}); + +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeConnectionId = faker.string.uuid(); + const deleteRowInTable = await request(app.getHttpServer()) + .delete(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteRowInTableRO = JSON.parse(deleteRowInTable.text); + t.is(deleteRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + t.is(deleteRowInTable.status, 403); + } catch (e) { + console.error(e); + throw e; + } +}); + +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTable = await request(app.getHttpServer()) + .delete(`/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteRowInTabbleRO = JSON.parse(deleteRowInTable.text); + t.is(deleteRowInTabbleRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); + +currentTest = 'GET /table/row/:slug'; + +test.serial(`${currentTest} should return row`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getRowInTable = await request(app.getHttpServer()) + .get(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=7`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getRowInTableRO = JSON.parse(getRowInTable.text); + t.is(getRowInTable.status, 200); + t.is(getRowInTableRO.row.id, 7); + t.is(Object.hasOwn(getRowInTableRO.row, 'created_at'), true); + t.is(Object.hasOwn(getRowInTableRO.row, 'updated_at'), true); + t.is(Object.hasOwn(getRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(getRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(getRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getRowInTableRO, 'readonly_fields'), true); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "DELETE /table/row/:slug"; +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeConnectionId = faker.string.uuid(); + const addRowInTable = await request(app.getHttpServer()) + .get(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=5`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial(`${currentTest} should return delete result`, async (t) => { +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -2341,96 +2178,28 @@ test.serial(`${currentTest} should return delete result`, async (t) => { secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const deleteRowInTable = await request(app.getHttpServer()) - .delete( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=19`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(deleteRowInTable.status, 200); + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTable = await request(app.getHttpServer()) + .get(`/table/row/${connections.firstId}?tableName=${fakeTableName}&id=5`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; } }); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeConnectionId = faker.string.uuid(); - const deleteRowInTable = await request(app.getHttpServer()) - .delete( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteRowInTableRO = JSON.parse(deleteRowInTable.text); - t.is(deleteRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - t.is(deleteRowInTable.status, 403); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTable = await request(app.getHttpServer()) - .delete( - `/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteRowInTabbleRO = JSON.parse(deleteRowInTable.text); - t.is(deleteRowInTabbleRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +//****************************** TABLE LOGS CONTROLLER TESTS ******************************// -currentTest = "GET /table/row/:slug"; +currentTest = 'GET /logs/:slug'; -test.serial(`${currentTest} should return row`, async (t) => { +test.serial(`${currentTest} should return all found logs in connection'`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -2439,168 +2208,52 @@ test.serial(`${currentTest} should return row`, async (t) => { secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const getRowInTable = await request(app.getHttpServer()) - .get( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=7`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getRowInTableRO = JSON.parse(getRowInTable.text); - t.is(getRowInTable.status, 200); - t.is(getRowInTableRO.row.id, 7); - t.is(Object.hasOwn(getRowInTableRO.row, "created_at"), true); - t.is(Object.hasOwn(getRowInTableRO.row, "updated_at"), true); - t.is(Object.hasOwn(getRowInTableRO, "structure"), true); - t.is(Object.hasOwn(getRowInTableRO, "foreignKeys"), true); - t.is(Object.hasOwn(getRowInTableRO, "primaryColumns"), true); - t.is(Object.hasOwn(getRowInTableRO, "readonly_fields"), true); + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .send({ + [firstTableInfo.testTableColumnName]: randomName, + [firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTable.status, 201); + + const getTableLogs = await request(app.getHttpServer()) + .get(`/logs/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getRowInTableRO = JSON.parse(getTableLogs.text); + + t.is(getRowInTableRO.logs.length, 1); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'table_name'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'received_data'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'old_data'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'cognitoUserName'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'email'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'operationType'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'operationStatusResult'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'createdAt'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'connection_id'), true); } catch (e) { console.error(e); throw e; } }); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeConnectionId = faker.string.uuid(); - const addRowInTable = await request(app.getHttpServer()) - .get( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=5`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTable = await request(app.getHttpServer()) - .get( - `/table/row/${connections.firstId}?tableName=${fakeTableName}&id=5`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -//****************************** TABLE LOGS CONTROLLER TESTS ******************************// - -currentTest = "GET /logs/:slug"; - -test.serial( - `${currentTest} should return all found logs in connection'`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .send({ - [firstTableInfo.testTableColumnName]: randomName, - [firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(addRowInTable.status, 201); - - const getTableLogs = await request(app.getHttpServer()) - .get(`/logs/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getRowInTableRO = JSON.parse(getTableLogs.text); - - t.is(getRowInTableRO.logs.length, 1); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "table_name"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "received_data"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "old_data"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "cognitoUserName"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "email"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "operationType"), true); - t.is( - Object.hasOwn(getRowInTableRO.logs[0], "operationStatusResult"), - true, - ); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "createdAt"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "connection_id"), true); - } catch (e) { - console.error(e); - throw e; - } - }, -); - test.serial( `${currentTest} should not return all found logs in connection, when table audit is disabled in connection'`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -2614,59 +2267,48 @@ test.serial( const created_at = new Date(); const updated_at = new Date(); - const updateConnection = - mockFactory.generateConnectionToTestPostgresDBInDocker(); + const updateConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); const updateConnectionResponse = await request(app.getHttpServer()) .put(`/connection/${connections.firstId}`) .send(updateConnection) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(updateConnectionResponse.status, 200); - const newConnectionProperties = - mockFactory.generateConnectionPropertiesUserExcluded(null, false); + const newConnectionProperties = mockFactory.generateConnectionPropertiesUserExcluded(null, false); - const createConnectionPropertiesResponse = await request( - app.getHttpServer(), - ) + const createConnectionPropertiesResponse = await request(app.getHttpServer()) .post(`/connection/properties/${connections.firstId}`) .send(newConnectionProperties) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const createConnectionPropertiesRO = JSON.parse( - createConnectionPropertiesResponse.text, - ); - console.log( - "🚀 ~ createConnectionPropertiesRO:", - createConnectionPropertiesRO, - ); + const createConnectionPropertiesRO = JSON.parse(createConnectionPropertiesResponse.text); + console.log('🚀 ~ createConnectionPropertiesRO:', createConnectionPropertiesRO); t.is(createConnectionPropertiesResponse.status, 201); const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) + .post(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) .send({ [firstTableInfo.testTableColumnName]: randomName, [firstTableInfo.testTableSecondColumnName]: randomEmail, created_at: created_at, updated_at: updated_at, }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(addRowInTable.status, 201); const getTableLogs = await request(app.getHttpServer()) .get(`/logs/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getRowInTableRO = JSON.parse(getTableLogs.text); t.is(getRowInTableRO.logs.length, 0); @@ -2679,14 +2321,12 @@ test.serial( //****************************** TABLE SETTINGS CONTROLLER TESTS ******************************// -currentTest = "GET /settings/"; +currentTest = 'GET /settings/'; test.skip(`${currentTest} should return empty object when table settings was not created`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -2696,12 +2336,10 @@ test.skip(`${currentTest} should return empty object when table settings was not users: { adminUserToken, simpleUserToken }, } = testData; const getTableSettings = await request(app.getHttpServer()) - .get( - `/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getTableSettingsRO = JSON.parse(getTableSettings.text); t.is(getTableSettings.status, 200); t.deepEqual(getTableSettingsRO, {}); @@ -2711,177 +2349,58 @@ test.skip(`${currentTest} should return empty object when table settings was not } }); -test.serial( - `${currentTest} 'should should return created table settings`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - ['id'], - [firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); - - const getTableSettings = await request(app.getHttpServer()) - .get( - `/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const _getTableSettingsRO = JSON.parse(getTableSettings.text); - t.is(getTableSettings.status, 200); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw an exception when you try get settings in connection where you do not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(createTableSettingsResponse.status, 201); - - const getTableSettings = await request(app.getHttpServer()) - .get( - `/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getTableSettingsRO = JSON.parse(getTableSettings.text); - t.is(getTableSettings.status, 403); - t.is(getTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -currentTest = "POST /settings/"; +test.serial(`${currentTest} 'should should return created table settings`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; -test.serial( - `${currentTest} should throw an exception do not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + ['id'], + [firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - 'users', - ['id'], - ['email'], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 403); - t.is( - JSON.parse(createTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const getTableSettings = await request(app.getHttpServer()) + .get(`/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const _getTableSettingsRO = JSON.parse(getTableSettings.text); + t.is(getTableSettings.status, 200); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( - `${currentTest} should throw an exception when you try create settings in connection where you do not have permission`, + `${currentTest} should throw an exception when you try get settings in connection where you do not have permission`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -2891,32 +2410,35 @@ test.serial( users: { adminUserToken, simpleUserToken }, } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}`, - ) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) .send(createTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 403); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const createTableSettingsRO = JSON.parse( - createTableSettingsResponse.text, - ); - t.is(createTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); + t.is(createTableSettingsResponse.status, 201); + + const getTableSettings = await request(app.getHttpServer()) + .get(`/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getTableSettingsRO = JSON.parse(getTableSettings.text); + t.is(getTableSettings.status, 403); + t.is(getTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -2924,191 +2446,84 @@ test.serial( }, ); -currentTest = "PUT /settings/"; +currentTest = 'POST /settings/'; test.serial(`${currentTest} should throw an exception do not have permission`, async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - ['id'], - [firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const updateTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - [firstTableInfo.testTableSecondColumnName], - ['id'], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + 'users', + ['id'], + ['email'], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); - const updateTableSettingsResponse = await request(app.getHttpServer()) - .put( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`, - ) - .send(updateTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(updateTableSettingsResponse.status, 403); - t.is( - JSON.parse(updateTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`) + .send(createTableSettingsDTO) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 403); + t.is(JSON.parse(createTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( - `${currentTest} should throw an exception when you try update settings in connection where you do not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); - - const updateTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - [firstTableInfo.testTableSecondColumnName], - ['id'], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + `${currentTest} should throw an exception when you try create settings in connection where you do not have permission`, + async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const updateTableSettingsResponse = await request(app.getHttpServer()) - .put( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}}`, - ) - .send(updateTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(updateTableSettingsResponse.status, 403); - t.is( - JSON.parse(updateTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, ); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -currentTest = "DELETE /settings/"; - -test.serial(`${currentTest} should return array without deleted table settings`, async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - ['id'], - [firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}`) .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); - - const deleteTableSettingsResponse = await request(app.getHttpServer()) - .delete( - `/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 403); - t.is(deleteTableSettingsResponse.status, 403); - t.is( - JSON.parse(deleteTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); + t.is(createTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -3116,73 +2531,72 @@ test.serial(`${currentTest} should return array without deleted table settings`, }, ); -test.serial( - `${currentTest} should throw an exception when you try delete settings in connection where you do not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); +currentTest = 'PUT /settings/'; - const deleteTableSettingsResponse = await request(app.getHttpServer()) - .delete( - `/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteTableSettingsRO = JSON.parse( - deleteTableSettingsResponse.text, - ); - t.is(deleteTableSettingsResponse.status, 403); - t.is(deleteTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception do not have permission`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + ['id'], + [firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); -//****************************** TABLE WIDGETS CONTROLLER TESTS ******************************// + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const updateTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + [firstTableInfo.testTableSecondColumnName], + ['id'], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); -currentTest = "GET /widgets/:slug"; + const updateTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`) + .send(updateTableSettingsDTO) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(updateTableSettingsResponse.status, 403); + t.is(JSON.parse(updateTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( - `${currentTest} should return empty widgets array when widgets not created`, + `${currentTest} should throw an exception when you try update settings in connection where you do not have permission`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -3191,16 +2605,46 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const getTableWidgets = await request(app.getHttpServer()) - .get( - `/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(getTableWidgets.status, 200); - t.is(getTableWidgetsRO.length, 0); + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const updateTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + [firstTableInfo.testTableSecondColumnName], + ['id'], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); + + const updateTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}}`) + .send(updateTableSettingsDTO) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(updateTableSettingsResponse.status, 403); + t.is(JSON.parse(updateTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -3208,14 +2652,60 @@ test.serial( }, ); +currentTest = 'DELETE /settings/'; + +test.serial(`${currentTest} should return array without deleted table settings`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + ['id'], + [firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const deleteTableSettingsResponse = await request(app.getHttpServer()) + .delete(`/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteTableSettingsResponse.status, 403); + t.is(JSON.parse(deleteTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); + test.serial( - `${currentTest} should return array of table widgets for table`, + `${currentTest} should throw an exception when you try delete settings in connection where you do not have permission`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -3224,65 +2714,34 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); - const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", adminUserToken) - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 201); - t.is(typeof createTableWidgetRO, "object"); - t.is(createTableWidgetRO.length, 2); - t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); - t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); - t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); - const getTableWidgets = await request(app.getHttpServer()) - .get( - `/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - t.is(getTableWidgets.status, 200); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(getTableWidgetsRO.length, 2); - - const getTableStructureResponse = await request(app.getHttpServer()) - .get( - `/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - t.is(getTableStructureResponse.status, 200); - const getTableStructureRO = JSON.parse(getTableStructureResponse.text); - t.is(Object.hasOwn(getTableStructureRO, "table_widgets"), true); - t.is(getTableStructureRO.table_widgets.length, 2); - t.is( - getTableStructureRO.table_widgets[0].field_name, - newTableWidgets[0].field_name, - ); - t.is( - getTableStructureRO.table_widgets[1].widget_type, - newTableWidgets[1].widget_type, - ); - t.is( - compareTableWidgetsArrays( - getTableStructureRO.table_widgets, - newTableWidgets, - ), - true, - ); + const deleteTableSettingsResponse = await request(app.getHttpServer()) + .delete(`/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteTableSettingsRO = JSON.parse(deleteTableSettingsResponse.text); + t.is(deleteTableSettingsResponse.status, 403); + t.is(deleteTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -3290,14 +2749,100 @@ test.serial( }, ); +//****************************** TABLE WIDGETS CONTROLLER TESTS ******************************// + +currentTest = 'GET /widgets/:slug'; + +test.serial(`${currentTest} should return empty widgets array when widgets not created`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(getTableWidgets.status, 200); + t.is(getTableWidgetsRO.length, 0); + } catch (e) { + console.error(e); + throw e; + } +}); + +test.serial(`${currentTest} should return array of table widgets for table`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', adminUserToken) + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 201); + t.is(typeof createTableWidgetRO, 'object'); + t.is(createTableWidgetRO.length, 2); + t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); + t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); + t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); + + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + t.is(getTableWidgets.status, 200); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(getTableWidgetsRO.length, 2); + + const getTableStructureResponse = await request(app.getHttpServer()) + .get(`/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + t.is(getTableStructureResponse.status, 200); + const getTableStructureRO = JSON.parse(getTableStructureResponse.text); + t.is(Object.hasOwn(getTableStructureRO, 'table_widgets'), true); + t.is(getTableStructureRO.table_widgets.length, 2); + t.is(getTableStructureRO.table_widgets[0].field_name, newTableWidgets[0].field_name); + t.is(getTableStructureRO.table_widgets[1].widget_type, newTableWidgets[1].widget_type); + t.is(compareTableWidgetsArrays(getTableStructureRO.table_widgets, newTableWidgets), true); + } catch (e) { + console.error(e); + throw e; + } +}); + test.serial( `${currentTest} should throw an exception, when you try to get widgets from connection, when you do not have permissions`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -3306,31 +2851,26 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) + .post(`/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", adminUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', adminUserToken) + .set('Accept', 'application/json'); const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 201); - t.is(typeof createTableWidgetRO, "object"); + t.is(typeof createTableWidgetRO, 'object'); t.is(createTableWidgetRO.length, 2); const getTableWidgets = await request(app.getHttpServer()) - .get( - `/widgets/${connections.secondId}?tableName=${secondTableInfo.testTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .get(`/widgets/${connections.secondId}?tableName=${secondTableInfo.testTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); const getTableWidgetsRO = JSON.parse(getTableWidgets.text); t.is(getTableWidgets.status, 403); t.is(getTableWidgetsRO.message, Messages.DONT_HAVE_PERMISSIONS); @@ -3341,57 +2881,47 @@ test.serial( }, ); -currentTest = "POST /widget/:slug"; +currentTest = 'POST /widget/:slug'; -test.serial( - `${currentTest} should throw an exception do not have permissions`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw an exception do not have permissions`, async (t) => { + try { + const testData = + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); - const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}}`, - ) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 403); - t.is(createTableWidgetRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 403); + t.is(createTableWidgetRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception, when you try add widget in connection, when you do not have permissions`, async (t) => { try { const testData = - await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app, - ); + await createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions(app); const { connections, firstTableInfo, @@ -3400,20 +2930,17 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.secondId}?tableName=${secondTableInfo.testTableName}`, - ) + .post(`/widget/${connections.secondId}?tableName=${secondTableInfo.testTableName}`) .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 403); t.is(createTableWidgetRO.message, Messages.DONT_HAVE_PERMISSIONS); diff --git a/backend/test/ava-tests/saas-tests/user-with-table-only-permissions-e2e.test.ts b/backend/test/ava-tests/saas-tests/user-with-table-only-permissions-e2e.test.ts index 8e4b54ae3..957223730 100644 --- a/backend/test/ava-tests/saas-tests/user-with-table-only-permissions-e2e.test.ts +++ b/backend/test/ava-tests/saas-tests/user-with-table-only-permissions-e2e.test.ts @@ -1,38 +1,34 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ /* eslint-disable security/detect-object-injection */ -import { faker } from "@faker-js/faker"; -import { INestApplication, ValidationPipe } from "@nestjs/common"; -import { Test } from "@nestjs/testing"; -import test from "ava"; -import { ValidationError } from "class-validator"; -import cookieParser from "cookie-parser"; -import request from "supertest"; -import { ApplicationModule } from "../../../src/app.module.js"; -import { WinstonLogger } from "../../../src/entities/logging/winston-logger.js"; -import { - AccessLevelEnum, - QueryOrderingEnum, -} from "../../../src/enums/index.js"; -import { AllExceptionsFilter } from "../../../src/exceptions/all-exceptions.filter.js"; -import { ValidationException } from "../../../src/exceptions/custom-exceptions/validation-exception.js"; -import { Messages } from "../../../src/exceptions/text/messages.js"; -import { Cacher } from "../../../src/helpers/cache/cacher.js"; -import { Constants } from "../../../src/helpers/constants/constants.js"; -import { DatabaseModule } from "../../../src/shared/database/database.module.js"; -import { DatabaseService } from "../../../src/shared/database/database.service.js"; -import { MockFactory } from "../../mock.factory.js"; -import { compareTableWidgetsArrays } from "../../utils/compare-table-widgets-arrays.js"; -import { inviteUserInCompanyAndAcceptInvitation } from "../../utils/register-user-and-return-user-info.js"; -import { TestUtils } from "../../utils/test.utils.js"; -import { createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions } from "../../utils/user-with-different-permissions-utils.js"; +import { faker } from '@faker-js/faker'; +import { INestApplication, ValidationPipe } from '@nestjs/common'; +import { Test } from '@nestjs/testing'; +import test from 'ava'; +import { ValidationError } from 'class-validator'; +import cookieParser from 'cookie-parser'; +import request from 'supertest'; +import { ApplicationModule } from '../../../src/app.module.js'; +import { WinstonLogger } from '../../../src/entities/logging/winston-logger.js'; +import { AccessLevelEnum, QueryOrderingEnum } from '../../../src/enums/index.js'; +import { AllExceptionsFilter } from '../../../src/exceptions/all-exceptions.filter.js'; +import { ValidationException } from '../../../src/exceptions/custom-exceptions/validation-exception.js'; +import { Messages } from '../../../src/exceptions/text/messages.js'; +import { Cacher } from '../../../src/helpers/cache/cacher.js'; +import { Constants } from '../../../src/helpers/constants/constants.js'; +import { DatabaseModule } from '../../../src/shared/database/database.module.js'; +import { DatabaseService } from '../../../src/shared/database/database.service.js'; +import { MockFactory } from '../../mock.factory.js'; +import { compareTableWidgetsArrays } from '../../utils/compare-table-widgets-arrays.js'; +import { inviteUserInCompanyAndAcceptInvitation } from '../../utils/register-user-and-return-user-info.js'; +import { TestUtils } from '../../utils/test.utils.js'; +import { createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions } from '../../utils/user-with-different-permissions-utils.js'; let app: INestApplication; let _testUtils: TestUtils; let currentTest: string; const mockFactory = new MockFactory(); -const _newConnectionToPostgres = - mockFactory.generateConnectionToTestPostgresDBInDocker(); +const _newConnectionToPostgres = mockFactory.generateConnectionToTestPostgresDBInDocker(); const updateConnection = mockFactory.generateUpdateConnectionDto(); const newGroup1 = mockFactory.generateCreateGroupDto1(); const tablePermissions = { @@ -69,7 +65,7 @@ test.after(async () => { await Cacher.clearAllCache(); await app.close(); } catch (e) { - console.error("After tests error " + e); + console.error('After tests error ' + e); } }); @@ -77,55 +73,44 @@ test.after(async () => { //****************************** CONNECTION CONTROLLER -currentTest = "GET /connections/"; +currentTest = 'GET /connections/'; -test.serial( - `${currentTest} should return connections, where second user have access`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const findAll = await request(app.getHttpServer()) - .get("/connections") - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - - t.is(findAll.status, 200); - - const result = findAll.body.connections; - t.is(result.length, 5); - const nonTestConnection = result.find( - ({ connection }) => connection.id === connections.firstId, - ); - for (const key in nonTestConnection.connection) { - t.is(Constants.CONNECTION_KEYS_NONE_PERMISSION.includes(key), true); - } - } catch (e) { - console.error(e); - throw e; +test.serial(`${currentTest} should return connections, where second user have access`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const findAll = await request(app.getHttpServer()) + .get('/connections') + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + + t.is(findAll.status, 200); + + const result = findAll.body.connections; + t.is(result.length, 5); + const nonTestConnection = result.find(({ connection }) => connection.id === connections.firstId); + for (const key in nonTestConnection.connection) { + t.is(Constants.CONNECTION_KEYS_NONE_PERMISSION.includes(key), true); } - }, -); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "GET /connection/one/:slug"; +currentTest = 'GET /connection/one/:slug'; test.serial(`${currentTest} should return a found connection`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -138,9 +123,9 @@ test.serial(`${currentTest} should return a found connection`, async (t) => { const searchedConnectionId = connections.firstId; const findOneResponce = await request(app.getHttpServer()) .get(`/connection/one/${searchedConnectionId}`) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); t.is(findOneResponce.status, 200); const result = findOneResponce.body.connection; @@ -157,10 +142,7 @@ test.serial( `${currentTest} should throw an exception, when you do not have permission in this connection`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -174,14 +156,14 @@ test.serial( const findOneResponce = await request(app.getHttpServer()) .get(`/connection/one/${searchedConnectionId}`) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); // todo add checking connection object properties t.is(findOneResponce.status, 200); const findOneRO = JSON.parse(findOneResponce.text); - t.is(Object.hasOwn(findOneRO, "host"), false); + t.is(Object.hasOwn(findOneRO, 'host'), false); } catch (e) { console.error(e); throw e; @@ -189,52 +171,40 @@ test.serial( }, ); -currentTest = "PUT /connection"; +currentTest = 'PUT /connection'; -test.serial( - `${currentTest} should throw exception you do not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw exception you do not have permission`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const updateConnectionResponse = await request(app.getHttpServer()) - .put(`/connection/${connections.firstId}`) - .send(updateConnection) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const updateConnectionResponse = await request(app.getHttpServer()) + .put(`/connection/${connections.firstId}`) + .send(updateConnection) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(updateConnectionResponse.status, 403); - t.is( - JSON.parse(updateConnectionResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(updateConnectionResponse.status, 403); + t.is(JSON.parse(updateConnectionResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should return throw an exception, when you try update a connection without permissions in it`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -246,15 +216,12 @@ test.serial( const updateConnectionResponse = await request(app.getHttpServer()) .put(`/connection/${connections.secondId}`) .send(updateConnection) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(updateConnectionResponse.status, 403); - t.is( - JSON.parse(updateConnectionResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + t.is(JSON.parse(updateConnectionResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -262,57 +229,48 @@ test.serial( }, ); -currentTest = "DELETE /connection/:slug"; - -test.serial( - `${currentTest} should throw an exception do not have permissions`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +currentTest = 'DELETE /connection/:slug'; - const response = await request(app.getHttpServer()) - .put(`/connection/delete/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(response.status, 403); - t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); +test.serial(`${currentTest} should throw an exception do not have permissions`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - //deleted connection found in database - const findOneResponce = await request(app.getHttpServer()) - .get(`/connection/one/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const response = await request(app.getHttpServer()) + .put(`/connection/delete/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(response.status, 403); + t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); + + //deleted connection found in database + const findOneResponce = await request(app.getHttpServer()) + .get(`/connection/one/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(findOneResponce.status, 200); - t.is(JSON.parse(findOneResponce.text).connection.id, connections.firstId); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(findOneResponce.status, 200); + t.is(JSON.parse(findOneResponce.text).connection.id, connections.firstId); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception, when you try to delete connection without permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -324,18 +282,18 @@ test.serial( const response = await request(app.getHttpServer()) .put(`/connection/delete/${connections.secondId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 403); t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); //connection wasn't deleted const findOneResponce = await request(app.getHttpServer()) .get(`/connection/one/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(findOneResponce.status, 200); } catch (e) { @@ -345,52 +303,40 @@ test.serial( }, ); -currentTest = "POST /connection/group/:slug"; +currentTest = 'POST /connection/group/:slug'; -test.serial( - `${currentTest} should throw an exception don not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw an exception don not have permission`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - t.is(createGroupResponse.status, 403); - t.is( - JSON.parse(createGroupResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(createGroupResponse.status, 403); + t.is(JSON.parse(createGroupResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception when you try add group in connection without permission in it`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -401,16 +347,13 @@ test.serial( } = testData; const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.secondId}`) - .set("Cookie", simpleUserToken) + .set('Cookie', simpleUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createGroupResponse.status, 403); - t.is( - JSON.parse(createGroupResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + t.is(JSON.parse(createGroupResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -418,69 +361,60 @@ test.serial( }, ); -currentTest = "PUT /connection/group/:slug"; +currentTest = 'PUT /connection/group/:slug'; -test.serial( - `${currentTest} should return connection without deleted group result`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should return connection without deleted group result`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connections.firstId}`) - .set("Cookie", adminUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connections.firstId}`) + .set('Cookie', adminUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - // create group in connection - let result = createGroupResponse.body; - t.is(createGroupResponse.status, 201); + // create group in connection + let result = createGroupResponse.body; + t.is(createGroupResponse.status, 201); - t.is(Object.hasOwn(result, "id"), true); - t.is(result.title, newGroup1.title); + t.is(Object.hasOwn(result, 'id'), true); + t.is(result.title, newGroup1.title); - const createGroupRO = JSON.parse(createGroupResponse.text); + const createGroupRO = JSON.parse(createGroupResponse.text); - const response = await request(app.getHttpServer()) - .put(`/connection/group/delete/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .send({ groupId: createGroupRO.id }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const response = await request(app.getHttpServer()) + .put(`/connection/group/delete/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .send({ groupId: createGroupRO.id }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - //after deleting group - result = response.body; + //after deleting group + result = response.body; - t.is(response.status, 403); - t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + t.is(response.status, 403); + t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception, when you try delete group in connection without permissions`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -491,27 +425,27 @@ test.serial( } = testData; const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.secondId}`) - .set("Cookie", adminUserToken) + .set('Cookie', adminUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); // create group in connection const result = createGroupResponse.body; t.is(createGroupResponse.status, 201); - t.is(Object.hasOwn(result, "id"), true); + t.is(Object.hasOwn(result, 'id'), true); t.is(result.title, newGroup1.title); const createGroupRO = JSON.parse(createGroupResponse.text); const response = await request(app.getHttpServer()) .put(`/connection/group/delete/${connections.secondId}`) - .set("Cookie", simpleUserToken) + .set('Cookie', simpleUserToken) .send({ groupId: createGroupRO.id }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 403); t.is(JSON.parse(response.text).message, Messages.DONT_HAVE_PERMISSIONS); @@ -522,14 +456,11 @@ test.serial( }, ); -currentTest = "GET /connection/groups/:slug"; +currentTest = 'GET /connection/groups/:slug'; test.serial(`${currentTest} should groups in connection`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -543,28 +474,28 @@ test.serial(`${currentTest} should groups in connection`, async (t) => { const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.firstId}`) - .set("Cookie", adminUserToken) + .set('Cookie', adminUserToken) .send(newRandomGroup2) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createGroupResponse.status, 201); const response = await request(app.getHttpServer()) .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 200); const result = JSON.parse(response.text); const _groupId = result[0].group.id; - t.is(Object.hasOwn(result[0].group, "title"), true); + t.is(Object.hasOwn(result[0].group, 'title'), true); t.is(result[0].accessLevel, AccessLevelEnum.none); const index = result.findIndex((el: any) => { - return el.group.title === "Admin"; + return el.group.title === 'Admin'; }); t.is(index >= 0, false); @@ -578,10 +509,7 @@ test.serial( `${currentTest} it should throw an exception, when you try get groups in connection, where you do not have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -592,18 +520,18 @@ test.serial( } = testData; const createGroupResponse = await request(app.getHttpServer()) .post(`/connection/group/${connections.secondId}`) - .set("Cookie", adminUserToken) + .set('Cookie', adminUserToken) .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createGroupResponse.status, 201); const response = await request(app.getHttpServer()) .get(`/connection/groups/${connections.secondId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(response.status, 200); const result = JSON.parse(response.text); @@ -615,16 +543,126 @@ test.serial( }, ); -currentTest = "GET /connection/permissions"; +currentTest = 'GET /connection/permissions'; + +test.serial(`${currentTest} should return permissions object for current group in current connection`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const groupId = getGroupsRO[0].group.id; + + const response = await request(app.getHttpServer()) + .get(`/connection/permissions?connectionId=${connections.firstId}&groupId=${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const result = JSON.parse(response.text); + t.is(response.status, 200); + + t.is(Object.hasOwn(result, 'connection'), true); + t.is(Object.hasOwn(result, 'group'), true); + t.is(Object.hasOwn(result, 'tables'), true); + t.is(typeof result.connection, 'object'); + t.is(typeof result.group, 'object'); + t.is(result.connection.connectionId, connections.firstId); + t.is(result.group.groupId, groupId); + t.is(result.connection.accessLevel, AccessLevelEnum.none); + t.is(result.group.accessLevel, AccessLevelEnum.none); + t.is(typeof result.tables, 'object'); + + const { tables } = result; + const tableIndex = tables.findIndex((table: any) => table.tableName === firstTableInfo.testTableName); + t.is(tables.length > 0, true); + t.is(typeof tables[tableIndex], 'object'); + t.is(Object.hasOwn(tables[tableIndex], 'accessLevel'), true); + t.is(tables[tableIndex].accessLevel.visibility, tablePermissions.visibility); + t.is(tables[tableIndex].accessLevel.readonly, tablePermissions.readonly); + t.is(tables[tableIndex].accessLevel.add, tablePermissions.add); + t.is(tables[tableIndex].accessLevel.delete, tablePermissions.delete); + t.is(tables[tableIndex].accessLevel.edit, tablePermissions.edit); + } catch (e) { + console.error(e); + throw e; + } +}); + +currentTest = 'GET /connection/user/permissions'; + +test.serial(`${currentTest} should return permissions object for current group in current connection`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const groupId = getGroupsRO[0].group.id; + + const response = await request(app.getHttpServer()) + .get(`/connection/user/permissions?connectionId=${connections.firstId}&groupId=${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(response.status, 200); + const result = JSON.parse(response.text); + + t.is(Object.hasOwn(result, 'connection'), true); + t.is(Object.hasOwn(result, 'group'), true); + t.is(Object.hasOwn(result, 'tables'), true); + t.is(typeof result.connection, 'object'); + t.is(typeof result.group, 'object'); + t.is(result.connection.connectionId, connections.firstId); + t.is(result.group.groupId, groupId); + t.is(result.connection.accessLevel, AccessLevelEnum.none); + t.is(result.group.accessLevel, AccessLevelEnum.none); + t.is(typeof result.tables, 'object'); + + const { tables } = result; + const foundTableIndex = tables.findIndex((table) => table.tableName === firstTableInfo.testTableName); + t.is(tables.length > 0, true); + t.is(typeof tables[foundTableIndex], 'object'); + t.is(Object.hasOwn(tables[foundTableIndex], 'accessLevel'), true); + t.is(tables[foundTableIndex].accessLevel.visibility, tablePermissions.visibility); + t.is(tables[foundTableIndex].accessLevel.readonly, tablePermissions.readonly); + t.is(tables[foundTableIndex].accessLevel.add, tablePermissions.add); + t.is(tables[foundTableIndex].accessLevel.delete, tablePermissions.delete); + t.is(tables[foundTableIndex].accessLevel.edit, tablePermissions.edit); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( - `${currentTest} should return permissions object for current group in current connection`, + `${currentTest} should return permissions object for current group in current connection for current user`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -633,51 +671,36 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; + const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/connection/groups/${connections.secondId}`) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); + const groupId = getGroupsRO[0].group.id; const response = await request(app.getHttpServer()) - .get( - `/connection/permissions?connectionId=${connections.firstId}&groupId=${groupId}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const result = JSON.parse(response.text); + .get(`/connection/user/permissions?connectionId=${connections.secondId}&groupId=${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(response.status, 200); + const result = JSON.parse(response.text); - t.is(Object.hasOwn(result, "connection"), true); - t.is(Object.hasOwn(result, "group"), true); - t.is(Object.hasOwn(result, "tables"), true); - t.is(typeof result.connection, "object"); - t.is(typeof result.group, "object"); - t.is(result.connection.connectionId, connections.firstId); + t.is(Object.hasOwn(result, 'connection'), true); + t.is(Object.hasOwn(result, 'group'), true); + t.is(Object.hasOwn(result, 'tables'), true); + t.is(typeof result.connection, 'object'); + t.is(typeof result.group, 'object'); + t.is(result.connection.connectionId, connections.secondId); t.is(result.group.groupId, groupId); t.is(result.connection.accessLevel, AccessLevelEnum.none); t.is(result.group.accessLevel, AccessLevelEnum.none); - t.is(typeof result.tables, "object"); - - const { tables } = result; - const tableIndex = tables.findIndex( - (table: any) => table.tableName === firstTableInfo.testTableName, - ); - t.is(tables.length > 0, true); - t.is(typeof tables[tableIndex], "object"); - t.is(Object.hasOwn(tables[tableIndex], "accessLevel"), true); - t.is( - tables[tableIndex].accessLevel.visibility, - tablePermissions.visibility, - ); - t.is(tables[tableIndex].accessLevel.readonly, tablePermissions.readonly); - t.is(tables[tableIndex].accessLevel.add, tablePermissions.add); - t.is(tables[tableIndex].accessLevel.delete, tablePermissions.delete); - t.is(tables[tableIndex].accessLevel.edit, tablePermissions.edit); + t.is(typeof result.tables, 'object'); } catch (e) { console.error(e); throw e; @@ -685,225 +708,81 @@ test.serial( }, ); -currentTest = "GET /connection/user/permissions"; +//****************************** GROUP CONTROLLER ******************************// -test.serial( - `${currentTest} should return permissions object for current group in current connection`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - const groupId = getGroupsRO[0].group.id; - - const response = await request(app.getHttpServer()) - .get( - `/connection/user/permissions?connectionId=${connections.firstId}&groupId=${groupId}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(response.status, 200); - const result = JSON.parse(response.text); - - t.is(Object.hasOwn(result, "connection"), true); - t.is(Object.hasOwn(result, "group"), true); - t.is(Object.hasOwn(result, "tables"), true); - t.is(typeof result.connection, "object"); - t.is(typeof result.group, "object"); - t.is(result.connection.connectionId, connections.firstId); - t.is(result.group.groupId, groupId); - t.is(result.connection.accessLevel, AccessLevelEnum.none); - t.is(result.group.accessLevel, AccessLevelEnum.none); - t.is(typeof result.tables, "object"); - - const { tables } = result; - const foundTableIndex = tables.findIndex( - (table) => table.tableName === firstTableInfo.testTableName, - ); - t.is(tables.length > 0, true); - t.is(typeof tables[foundTableIndex], "object"); - t.is(Object.hasOwn(tables[foundTableIndex], "accessLevel"), true); - t.is( - tables[foundTableIndex].accessLevel.visibility, - tablePermissions.visibility, - ); - t.is( - tables[foundTableIndex].accessLevel.readonly, - tablePermissions.readonly, - ); - t.is(tables[foundTableIndex].accessLevel.add, tablePermissions.add); - t.is(tables[foundTableIndex].accessLevel.delete, tablePermissions.delete); - t.is(tables[foundTableIndex].accessLevel.edit, tablePermissions.edit); - } catch (e) { - console.error(e); - throw e; - } - }, -); +currentTest = 'GET /groups/'; -test.serial( - `${currentTest} should return permissions object for current group in current connection for current user`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.secondId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - - const groupId = getGroupsRO[0].group.id; - - const response = await request(app.getHttpServer()) - .get( - `/connection/user/permissions?connectionId=${connections.secondId}&groupId=${groupId}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(response.status, 200); - const result = JSON.parse(response.text); - - t.is(Object.hasOwn(result, "connection"), true); - t.is(Object.hasOwn(result, "group"), true); - t.is(Object.hasOwn(result, "tables"), true); - t.is(typeof result.connection, "object"); - t.is(typeof result.group, "object"); - t.is(result.connection.connectionId, connections.secondId); - t.is(result.group.groupId, groupId); - t.is(result.connection.accessLevel, AccessLevelEnum.none); - t.is(result.group.accessLevel, AccessLevelEnum.none); - t.is(typeof result.tables, "object"); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -//****************************** GROUP CONTROLLER ******************************// - -currentTest = "GET /groups/"; - -test.serial( - `${currentTest} should return found groups with current user`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - users: { simpleUserToken }, - } = testData; +test.serial(`${currentTest} should return found groups with current user`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + users: { simpleUserToken }, + } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/groups/`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - const { groups, groupsCount } = getGroupsRO; - t.is(groupsCount, 1); - t.is(groups.length, 1); - t.is(Object.hasOwn(groups[0], "group"), true); - t.is(Object.hasOwn(groups[0], "accessLevel"), true); - - t.is(Object.hasOwn(groups[0].group, "title"), true); - t.is(Object.hasOwn(groups[0].group, "isMain"), true); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/groups/`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const { groups, groupsCount } = getGroupsRO; + t.is(groupsCount, 1); + t.is(groups.length, 1); + t.is(Object.hasOwn(groups[0], 'group'), true); + t.is(Object.hasOwn(groups[0], 'accessLevel'), true); + + t.is(Object.hasOwn(groups[0].group, 'title'), true); + t.is(Object.hasOwn(groups[0].group, 'isMain'), true); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "GET /group/users/:slug"; -test.serial( - `${currentTest} it should throw exception ${Messages.DONT_HAVE_PERMISSIONS}`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - const nonAdminGroupIndex = getGroupsRO.findIndex((element) => { - return !element.group.isMain; - }); - const groupId = getGroupsRO[nonAdminGroupIndex].group.id; - const response = await request(app.getHttpServer()) - .get(`/group/users/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(response.status, 403); - const getUsersRO = JSON.parse(response.text); - t.is(Object.hasOwn(getUsersRO, "message"), true); - t.is(getUsersRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +currentTest = 'GET /group/users/:slug'; +test.serial(`${currentTest} it should throw exception ${Messages.DONT_HAVE_PERMISSIONS}`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + const nonAdminGroupIndex = getGroupsRO.findIndex((element) => { + return !element.group.isMain; + }); + const groupId = getGroupsRO[nonAdminGroupIndex].group.id; + const response = await request(app.getHttpServer()) + .get(`/group/users/${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(response.status, 403); + const getUsersRO = JSON.parse(response.text); + t.is(Object.hasOwn(getUsersRO, 'message'), true); + t.is(getUsersRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} it should throw an exception when you try to receive user in group where you dont have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -914,9 +793,9 @@ test.serial( } = testData; const getGroupsResponse = await request(app.getHttpServer()) .get(`/connection/groups/${connections.secondId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); @@ -924,9 +803,9 @@ test.serial( const response = await request(app.getHttpServer()) .get(`/group/users/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getUsersRO = JSON.parse(response.text); t.is(getUsersRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { @@ -936,490 +815,419 @@ test.serial( }, ); -currentTest = "PUT /group/user"; +currentTest = 'PUT /group/user'; -test.serial( - `${currentTest} should throw exception ${Messages.DONT_HAVE_PERMISSIONS}`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - - const groupId = getGroupsRO[0].group.id; - - const email = faker.internet.email(); - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); - t.is(addUserInGroupResponse.status, 403); - t.is(Object.hasOwn(addUserInGroupRO, "message"), true); - t.is(addUserInGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw exception, when group id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - - const _groupId = getGroupsRO[0].group.id; - const email = faker.internet.email(); - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", simpleUserToken) - .send({ email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); - t.is(addUserInGroupResponse.status, 400); - t.is(addUserInGroupRO.message, Messages.GROUP_ID_MISSING); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw exception, when group id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(getGroupsResponse.status, 200); - const _getGroupsRO = JSON.parse(getGroupsResponse.text); - - const email = faker.internet.email(); - const groupId = faker.string.uuid(); - const addUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user") - .set("Cookie", simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); - t.is(addUserInGroupResponse.status, 400); - t.is(addUserInGroupRO.message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -currentTest = "DELETE /group/:slug"; - -test.serial( - `${currentTest} should throw ${Messages.DONT_HAVE_PERMISSIONS} exception`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(getGroupsResponse.status, 200); - const groupId = JSON.parse(getGroupsResponse.text)[0].group.id; - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteGroupRO = JSON.parse(deleteGroupResponse.text); - t.is(deleteGroupResponse.status, 403); - t.is(deleteGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw an exception when you try delete admin group`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - - const adminGroupIndex = getGroupsRO.findIndex( - (group) => group.group.isMain, - ); - - const groupId = getGroupsRO[adminGroupIndex].group.id; - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteGroupRO = JSON.parse(deleteGroupResponse.text); - t.is(deleteGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw exception ${Messages.DONT_HAVE_PERMISSIONS}`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; -test.serial( - `${currentTest} should throw an exception when group id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + + const groupId = getGroupsRO[0].group.id; + + const email = faker.internet.email(); + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); + t.is(addUserInGroupResponse.status, 403); + t.is(Object.hasOwn(addUserInGroupRO, 'message'), true); + t.is(addUserInGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); +test.serial(`${currentTest} should throw exception, when group id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + + const _groupId = getGroupsRO[0].group.id; + const email = faker.internet.email(); + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', simpleUserToken) + .send({ email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); + t.is(addUserInGroupResponse.status, 400); + t.is(addUserInGroupRO.message, Messages.GROUP_ID_MISSING); + } catch (e) { + console.error(e); + throw e; + } +}); - const _groupId = getGroupsRO[0].group.id; - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(deleteGroupResponse.status, 404); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw exception, when group id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getGroupsResponse.status, 200); + const _getGroupsRO = JSON.parse(getGroupsResponse.text); + + const email = faker.internet.email(); + const groupId = faker.string.uuid(); + const addUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addUserInGroupRO = JSON.parse(addUserInGroupResponse.text); + t.is(addUserInGroupResponse.status, 400); + t.is(addUserInGroupRO.message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when group id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +currentTest = 'DELETE /group/:slug'; - t.is(getGroupsResponse.status, 200); +test.serial(`${currentTest} should throw ${Messages.DONT_HAVE_PERMISSIONS} exception`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getGroupsResponse.status, 200); + const groupId = JSON.parse(getGroupsResponse.text)[0].group.id; + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteGroupRO = JSON.parse(deleteGroupResponse.text); + t.is(deleteGroupResponse.status, 403); + t.is(deleteGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); - const groupId = faker.string.uuid(); - const deleteGroupResponse = await request(app.getHttpServer()) - .delete(`/group/${groupId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteGroupRO = JSON.parse(deleteGroupResponse.text); - t.is(deleteGroupRO.message, Messages.CONNECTION_NOT_FOUND); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when you try delete admin group`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + + const adminGroupIndex = getGroupsRO.findIndex((group) => group.group.isMain); + + const groupId = getGroupsRO[adminGroupIndex].group.id; + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteGroupRO = JSON.parse(deleteGroupResponse.text); + t.is(deleteGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "PUT /group/user/delete"; +test.serial(`${currentTest} should throw an exception when group id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + + const _groupId = getGroupsRO[0].group.id; + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(deleteGroupResponse.status, 404); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception ${Messages.DONT_HAVE_PERMISSIONS}`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); +test.serial(`${currentTest} should throw an exception when group id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getGroupsResponse.status, 200); + + const groupId = faker.string.uuid(); + const deleteGroupResponse = await request(app.getHttpServer()) + .delete(`/group/${groupId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteGroupRO = JSON.parse(deleteGroupResponse.text); + t.is(deleteGroupRO.message, Messages.CONNECTION_NOT_FOUND); + } catch (e) { + console.error(e); + throw e; + } +}); - t.is(getGroupsResponse.status, 200); - const getGroupsRO = JSON.parse(getGroupsResponse.text); +currentTest = 'PUT /group/user/delete'; - const groupId = getGroupsRO[0].group.id; +test.serial(`${currentTest} should throw an exception ${Messages.DONT_HAVE_PERMISSIONS}`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); - const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( - testData.users.adminUserToken, - undefined, - app, - undefined, - ); + t.is(getGroupsResponse.status, 200); + const getGroupsRO = JSON.parse(getGroupsResponse.text); - const email = thirdTestUser.email; - - const deleteUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user/delete") - .set("Cookie", simpleUserToken) - .send({ groupId, email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(deleteUserInGroupResponse.status, 403); - const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); - t.is(deleteUserInGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const groupId = getGroupsRO[0].group.id; -test.serial( - `${currentTest} should throw exception, when group id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( + testData.users.adminUserToken, + undefined, + app, + undefined, + ); - t.is(getGroupsResponse.status, 200); - const _getGroupsRO = JSON.parse(getGroupsResponse.text); + const email = thirdTestUser.email; + + const deleteUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user/delete') + .set('Cookie', simpleUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(deleteUserInGroupResponse.status, 403); + const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); + t.is(deleteUserInGroupRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); - const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( - testData.users.adminUserToken, - undefined, - app, - undefined, - ); +test.serial(`${currentTest} should throw exception, when group id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(getGroupsResponse.status, 200); + const _getGroupsRO = JSON.parse(getGroupsResponse.text); + + const thirdTestUser = await inviteUserInCompanyAndAcceptInvitation( + testData.users.adminUserToken, + undefined, + app, + undefined, + ); - const email = thirdTestUser.email; - - const deleteUserInGroupResponse = await request(app.getHttpServer()) - .put("/group/user/delete") - .set("Cookie", simpleUserToken) - .send({ email }) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(deleteUserInGroupResponse.status, 400); - const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); - t.is(deleteUserInGroupRO.message, Messages.GROUP_ID_MISSING); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const email = thirdTestUser.email; + + const deleteUserInGroupResponse = await request(app.getHttpServer()) + .put('/group/user/delete') + .set('Cookie', simpleUserToken) + .send({ email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(deleteUserInGroupResponse.status, 400); + const deleteUserInGroupRO = JSON.parse(deleteUserInGroupResponse.text); + t.is(deleteUserInGroupRO.message, Messages.GROUP_ID_MISSING); + } catch (e) { + console.error(e); + throw e; + } +}); //****************************** PERMISSION CONTROLLER TESTS ******************************// -currentTest = "PUT permissions/:slug"; +currentTest = 'PUT permissions/:slug'; -test.serial( - `${currentTest} should throw an exception do not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connections.firstId}`) - .set("Cookie", adminUserToken) - .send(newGroup1) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createGroupRO = JSON.parse(createGroupResponse.text); - t.is(createGroupResponse.status, 201); - const newGroupId = createGroupRO.id; +test.serial(`${currentTest} should throw an exception do not have permission`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const newGroup1 = MockFactory.generateCreateGroupDtoWithRandomTitle(); + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connections.firstId}`) + .set('Cookie', adminUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createGroupRO = JSON.parse(createGroupResponse.text); + t.is(createGroupResponse.status, 201); + const newGroupId = createGroupRO.id; - const permissions = { - connection: { - connectionId: connections.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: newGroupId, - accessLevel: AccessLevelEnum.readonly, - }, - tables: [ - { - tableName: firstTableInfo.testTableName, - accessLevel: { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: false, - }, + const permissions = { + connection: { + connectionId: connections.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: newGroupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: firstTableInfo.testTableName, + accessLevel: { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: false, }, - ], - }; - - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put( - `/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`, - ) - .send({ permissions }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createOrUpdatePermissionRO = JSON.parse( - createOrUpdatePermissionResponse.text, - ); - t.is(createOrUpdatePermissionResponse.status, 403); - t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + }, + ], + }; + + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${newGroupId}?connectionId=${testData.connections.firstId}`) + .send({ permissions }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createOrUpdatePermissionRO = JSON.parse(createOrUpdatePermissionResponse.text); + t.is(createOrUpdatePermissionResponse.status, 403); + t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw ${Messages.DONT_HAVE_PERMISSIONS} exception object when you update permissions`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -1430,9 +1238,9 @@ test.serial( const getGroupsResponse = await request(app.getHttpServer()) .get(`/connection/groups/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getGroupsResponse.status, 200); const getGroupsRO = JSON.parse(getGroupsResponse.text); @@ -1462,17 +1270,13 @@ test.serial( ], }; - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) .put(`/permissions/${groupId}?connectionId=${connections.firstId}`) .send({ permissions }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createOrUpdatePermissionRO = JSON.parse( - createOrUpdatePermissionResponse.text, - ); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createOrUpdatePermissionRO = JSON.parse(createOrUpdatePermissionResponse.text); t.is(createOrUpdatePermissionResponse.status, 403); t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { @@ -1482,157 +1286,123 @@ test.serial( }, ); -test.serial( - `${currentTest} should throw an exception, when you try change admin group`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups: { firstAdminGroupId }, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw an exception, when you try change admin group`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups: { firstAdminGroupId }, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const permissions = { - connection: { - connectionId: connections.firstId, - accessLevel: AccessLevelEnum.edit, - }, - group: { - groupId: firstAdminGroupId, - accessLevel: AccessLevelEnum.none, - }, - tables: [ - { - tableName: firstTableInfo.testTableName, - accessLevel: { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: false, - }, + const permissions = { + connection: { + connectionId: connections.firstId, + accessLevel: AccessLevelEnum.edit, + }, + group: { + groupId: firstAdminGroupId, + accessLevel: AccessLevelEnum.none, + }, + tables: [ + { + tableName: firstTableInfo.testTableName, + accessLevel: { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: false, }, - ], - }; - - const createOrUpdatePermissionResponse = await request( - app.getHttpServer(), - ) - .put(`/permissions/${firstAdminGroupId}`) - .send({ permissions }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const createOrUpdatePermissionRO = JSON.parse( - createOrUpdatePermissionResponse.text, - ); - t.is(createOrUpdatePermissionResponse.status, 403); - t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + }, + ], + }; + + const createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${firstAdminGroupId}`) + .send({ permissions }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createOrUpdatePermissionRO = JSON.parse(createOrUpdatePermissionResponse.text); + t.is(createOrUpdatePermissionResponse.status, 403); + t.is(createOrUpdatePermissionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); //****************************** TABLE CONTROLLER TESTS ******************************// -currentTest = "GET /connection/tables/:slug"; +currentTest = 'GET /connection/tables/:slug'; -test.serial( - `${currentTest} should return all tables in connection`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesInConnection = await request(app.getHttpServer()) - .get(`/connection/tables/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesInConnection.status, 200); - const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); - t.is(getTablesInConnectionRO.length > 0, true); - const tableIndex = getTablesInConnectionRO.findIndex( - (table: any) => table.table === testData.firstTableInfo.testTableName, - ); - t.is( - getTablesInConnectionRO[tableIndex].table, - testData.firstTableInfo.testTableName, - ); - t.is(typeof getTablesInConnectionRO[tableIndex].permissions, "object"); - const { - visibility, - readonly, - add, - delete: del, - edit, - } = getTablesInConnectionRO[0].permissions; - t.is(visibility, tablePermissions.visibility); - t.is(readonly, tablePermissions.readonly); - t.is(del, tablePermissions.delete); - t.is(edit, tablePermissions.edit); - t.is(add, tablePermissions.add); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should return all tables in connection`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesInConnection = await request(app.getHttpServer()) + .get(`/connection/tables/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesInConnection.status, 200); + const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); + t.is(getTablesInConnectionRO.length > 0, true); + const tableIndex = getTablesInConnectionRO.findIndex( + (table: any) => table.table === testData.firstTableInfo.testTableName, + ); + t.is(getTablesInConnectionRO[tableIndex].table, testData.firstTableInfo.testTableName); + t.is(typeof getTablesInConnectionRO[tableIndex].permissions, 'object'); + const { visibility, readonly, add, delete: del, edit } = getTablesInConnectionRO[0].permissions; + t.is(visibility, tablePermissions.visibility); + t.is(readonly, tablePermissions.readonly); + t.is(del, tablePermissions.delete); + t.is(edit, tablePermissions.edit); + t.is(add, tablePermissions.add); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception, when connection id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesInConnection = await request(app.getHttpServer()) - .get(`/connection/tables/`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesInConnection.status, 404); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception, when connection id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesInConnection = await request(app.getHttpServer()) + .get(`/connection/tables/`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesInConnection.status, 404); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception, when connection id passed in request is incorrect`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -1644,9 +1414,9 @@ test.serial( const fakeConnectionId = faker.string.uuid(); const getTablesInConnection = await request(app.getHttpServer()) .get(`/connection/tables/${fakeConnectionId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getTablesInConnection.status, 400); const getTablesInConnectionRO = JSON.parse(getTablesInConnection.text); t.is(getTablesInConnectionRO.message, Messages.CONNECTION_NOT_FOUND); @@ -1657,14 +1427,11 @@ test.serial( }, ); -currentTest = "GET /table/rows/:slug"; +currentTest = 'GET /table/rows/:slug'; test.serial(`${currentTest} should return found rows from table`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -1674,26 +1441,17 @@ test.serial(`${currentTest} should return found rows from table`, async (t) => { users: { adminUserToken, simpleUserToken }, } = testData; const getTableRows = await request(app.getHttpServer()) - .get( - `/table/rows/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/table/rows/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(getTableRows.status, 200); const getTableRowsRO = JSON.parse(getTableRows.text); - const { - rows, - primaryColumns, - pagination, - sortable_by, - structure, - foreignKeys, - } = getTableRowsRO; + const { rows, primaryColumns, pagination, sortable_by, structure, foreignKeys } = getTableRowsRO; t.is(rows.length, Constants.DEFAULT_PAGINATION.perPage); t.is(primaryColumns.length, 1); - t.is(primaryColumns[0].column_name, "id"); - t.is(primaryColumns[0].data_type, "integer"); + t.is(primaryColumns[0].column_name, 'id'); + t.is(primaryColumns[0].data_type, 'integer'); t.is(sortable_by.length, 0); t.is(structure.length, 5); t.is(foreignKeys.length, 0); @@ -1703,109 +1461,86 @@ test.serial(`${currentTest} should return found rows from table`, async (t) => { } }); -test.serial( - `${currentTest} should throw an exception when connection id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesRows = await request(app.getHttpServer()) - .get(`/table/rows/?tableName=${firstTableInfo.testTableName}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesRows.status, 404); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesRows = await request(app.getHttpServer()) + .get(`/table/rows/?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesRows.status, 404); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrec`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeId = faker.string.uuid(); - const getTableRows = await request(app.getHttpServer()) - .get( - `/table/rows/${fakeId}?tableName=${testData.firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTableRows.status, 403); - const getTablesInConnectionRO = JSON.parse(getTableRows.text); - t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrec`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeId = faker.string.uuid(); + const getTableRows = await request(app.getHttpServer()) + .get(`/table/rows/${fakeId}?tableName=${testData.firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTableRows.status, 403); + const getTablesInConnectionRO = JSON.parse(getTableRows.text); + t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTablesRows = await request(app.getHttpServer()) - .get(`/table/rows/${connections.firstId}?tableName=${fakeTableName}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesRows.status, 403); - const getTablesInConnectionRO = JSON.parse(getTablesRows.text); - t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTablesRows = await request(app.getHttpServer()) + .get(`/table/rows/${connections.firstId}?tableName=${fakeTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesRows.status, 403); + const getTablesInConnectionRO = JSON.parse(getTablesRows.text); + t.is(getTablesInConnectionRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "GET /table/structure/:slug"; +currentTest = 'GET /table/structure/:slug'; test.serial(`${currentTest} should return table structure`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -1815,27 +1550,19 @@ test.serial(`${currentTest} should return table structure`, async (t) => { users: { adminUserToken, simpleUserToken }, } = testData; const getTablesStructure = await request(app.getHttpServer()) - .get( - `/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getTableStructureRO = JSON.parse(getTablesStructure.text); t.is(getTablesStructure.status, 200); - const { - structure, - primaryColumns, - foreignKeys, - readonly_fields, - table_widgets, - } = getTableStructureRO; + const { structure, primaryColumns, foreignKeys, readonly_fields, table_widgets } = getTableStructureRO; t.is(structure.length, 5); t.is(primaryColumns.length, 1); - t.is(primaryColumns[0].column_name, "id"); - t.is(primaryColumns[0].data_type, "integer"); + t.is(primaryColumns[0].column_name, 'id'); + t.is(primaryColumns[0].data_type, 'integer'); t.is(readonly_fields.length, 0); t.is(table_widgets.length, 0); t.is(foreignKeys.length, 0); @@ -1845,144 +1572,113 @@ test.serial(`${currentTest} should return table structure`, async (t) => { } }); -test.serial( - `${currentTest} should throw an exception when connection id not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const getTablesStructure = await request(app.getHttpServer()) - .get(`/table/structure/?tableName=${firstTableInfo.testTableName}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 404); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 404); + } catch (e) { + console.error(e); + throw e; + } +}); - const fakeConnectionId = faker.string.uuid(); - const getTablesStructure = await request(app.getHttpServer()) - .get( - `/table/structure/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 403); - const getTablesStructureRO = JSON.parse(getTablesStructure.text); - t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; -test.serial( - `${currentTest} should throw an exception when table name not passed in request`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTablesStructure = await request(app.getHttpServer()) - .get(`/table/structure/${connections.firstId}?tableName=`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 400); - const getTablesStructureRO = JSON.parse(getTablesStructure.text); - t.is(getTablesStructureRO.message, Messages.TABLE_NAME_MISSING); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const fakeConnectionId = faker.string.uuid(); + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 403); + const getTablesStructureRO = JSON.parse(getTablesStructure.text); + t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const getTablesStructure = await request(app.getHttpServer()) - .get( - `/table/structure/${connections.firstId}?tableName=${fakeTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(getTablesStructure.status, 403); - const getTablesStructureRO = JSON.parse(getTablesStructure.text); - t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when table name not passed in request`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${connections.firstId}?tableName=`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 400); + const getTablesStructureRO = JSON.parse(getTablesStructure.text); + t.is(getTablesStructureRO.message, Messages.TABLE_NAME_MISSING); + } catch (e) { + console.error(e); + throw e; + } +}); + +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const getTablesStructure = await request(app.getHttpServer()) + .get(`/table/structure/${connections.firstId}?tableName=${fakeTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(getTablesStructure.status, 403); + const getTablesStructureRO = JSON.parse(getTablesStructure.text); + t.is(getTablesStructureRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "POST /table/row/:slug"; +currentTest = 'POST /table/row/:slug'; test.serial(`${currentTest} should return added row`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -1998,132 +1694,110 @@ test.serial(`${currentTest} should return added row`, async (t) => { const created_at = new Date(); const updated_at = new Date(); const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) + .post(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) .send({ [firstTableInfo.testTableColumnName]: randomName, [firstTableInfo.testTableSecondColumnName]: randomEmail, created_at: created_at, updated_at: updated_at, }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const addRowInTableRO = JSON.parse(addRowInTable.text); t.is(addRowInTable.status, 201); - t.is(Object.hasOwn(addRowInTableRO.row, "id"), true); + t.is(Object.hasOwn(addRowInTableRO.row, 'id'), true); t.is(addRowInTableRO.row[firstTableInfo.testTableColumnName], randomName); - t.is( - addRowInTableRO.row[firstTableInfo.testTableSecondColumnName], - randomEmail, - ); - t.is(Object.hasOwn(addRowInTableRO.row, "created_at"), true); - t.is(Object.hasOwn(addRowInTableRO.row, "updated_at"), true); - t.is(Object.hasOwn(addRowInTableRO, "structure"), true); - t.is(Object.hasOwn(addRowInTableRO, "foreignKeys"), true); - t.is(Object.hasOwn(addRowInTableRO, "primaryColumns"), true); - t.is(Object.hasOwn(addRowInTableRO, "readonly_fields"), true); + t.is(addRowInTableRO.row[firstTableInfo.testTableSecondColumnName], randomEmail); + t.is(Object.hasOwn(addRowInTableRO.row, 'created_at'), true); + t.is(Object.hasOwn(addRowInTableRO.row, 'updated_at'), true); + t.is(Object.hasOwn(addRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(addRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(addRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(addRowInTableRO, 'readonly_fields'), true); } catch (e) { console.error(e); throw e; } }); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const fakeConnectionId = faker.string.uuid(); - const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`, - ) - .send({ - [firstTableInfo.testTableColumnName]: randomName, - [firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeConnectionId = faker.string.uuid(); + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}`) + .send({ + [firstTableInfo.testTableColumnName]: randomName, + [firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTable = await request(app.getHttpServer()) - .post(`/table/row/${connections.firstId}?tableName=${fakeTableName}`) - .send({ - [firstTableInfo.testTableColumnName]: randomName, - [firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${connections.firstId}?tableName=${fakeTableName}`) + .send({ + [firstTableInfo.testTableColumnName]: randomName, + [firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "PUT /table/row/:slug"; +currentTest = 'PUT /table/row/:slug'; test.serial( `${currentTest} should throw an exception do not have permission, when you do not have edit permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -2138,18 +1812,16 @@ test.serial( const created_at = new Date(); const updated_at = new Date(); const updateRowInTable = await request(app.getHttpServer()) - .put( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=2`, - ) + .put(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=2`) .send({ name: randomName, email: randomEmail, created_at: created_at, updated_at: updated_at, }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const addRowInTableRO = JSON.parse(updateRowInTable.text); t.is(updateRowInTable.status, 403); t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); @@ -2160,100 +1832,105 @@ test.serial( }, ); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const fakeConnectionId = faker.string.uuid(); - const addRowInTable = await request(app.getHttpServer()) - .put( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`, - ) - .send({ - name: randomName, - email: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeConnectionId = faker.string.uuid(); + const addRowInTable = await request(app.getHttpServer()) + .put(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`) + .send({ + name: randomName, + email: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTable = await request(app.getHttpServer()) - .put( - `/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`, - ) - .send({ - name: randomName, - email: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTable = await request(app.getHttpServer()) + .put(`/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`) + .send({ + name: randomName, + email: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); + +currentTest = 'DELETE /table/row/:slug'; -currentTest = "DELETE /table/row/:slug"; +test.serial(`${currentTest} should return delete result`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const deleteRowInTable = await request(app.getHttpServer()) + .delete(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=19`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteRowInTable.status, 200); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial(`${currentTest} should return delete result`, async (t) => { +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -2262,96 +1939,51 @@ test.serial(`${currentTest} should return delete result`, async (t) => { secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; + const fakeConnectionId = faker.string.uuid(); const deleteRowInTable = await request(app.getHttpServer()) - .delete( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=19`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(deleteRowInTable.status, 200); + .delete(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteRowInTableRO = JSON.parse(deleteRowInTable.text); + t.is(deleteRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + t.is(deleteRowInTable.status, 403); } catch (e) { console.error(e); throw e; } }); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeConnectionId = faker.string.uuid(); - const deleteRowInTable = await request(app.getHttpServer()) - .delete( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=1`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteRowInTableRO = JSON.parse(deleteRowInTable.text); - t.is(deleteRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - t.is(deleteRowInTable.status, 403); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const deleteRowInTable = await request(app.getHttpServer()) - .delete( - `/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteRowInTabbleRO = JSON.parse(deleteRowInTable.text); - t.is(deleteRowInTabbleRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const deleteRowInTable = await request(app.getHttpServer()) + .delete(`/table/row/${connections.firstId}?tableName=${fakeTableName}&id=1`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteRowInTabbleRO = JSON.parse(deleteRowInTable.text); + t.is(deleteRowInTabbleRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -currentTest = "GET /table/row/:slug"; +currentTest = 'GET /table/row/:slug'; test.serial(`${currentTest} should return row`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -2361,167 +1993,135 @@ test.serial(`${currentTest} should return row`, async (t) => { users: { adminUserToken, simpleUserToken }, } = testData; const getRowInTable = await request(app.getHttpServer()) - .get( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=7`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}&id=7`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getRowInTableRO = JSON.parse(getRowInTable.text); t.is(getRowInTable.status, 200); t.is(getRowInTableRO.row.id, 7); - t.is(Object.hasOwn(getRowInTableRO.row, "created_at"), true); - t.is(Object.hasOwn(getRowInTableRO.row, "updated_at"), true); - t.is(Object.hasOwn(getRowInTableRO, "structure"), true); - t.is(Object.hasOwn(getRowInTableRO, "foreignKeys"), true); - t.is(Object.hasOwn(getRowInTableRO, "primaryColumns"), true); - t.is(Object.hasOwn(getRowInTableRO, "readonly_fields"), true); + t.is(Object.hasOwn(getRowInTableRO.row, 'created_at'), true); + t.is(Object.hasOwn(getRowInTableRO.row, 'updated_at'), true); + t.is(Object.hasOwn(getRowInTableRO, 'structure'), true); + t.is(Object.hasOwn(getRowInTableRO, 'foreignKeys'), true); + t.is(Object.hasOwn(getRowInTableRO, 'primaryColumns'), true); + t.is(Object.hasOwn(getRowInTableRO, 'readonly_fields'), true); } catch (e) { console.error(e); throw e; } }); -test.serial( - `${currentTest} should throw an exception when connection id passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeConnectionId = faker.string.uuid(); - const addRowInTable = await request(app.getHttpServer()) - .get( - `/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=5`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when connection id passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeConnectionId = faker.string.uuid(); + const addRowInTable = await request(app.getHttpServer()) + .get(`/table/row/${fakeConnectionId}?tableName=${firstTableInfo.testTableName}&id=5`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); -test.serial( - `${currentTest} should throw an exception when table name passed in request is incorrect`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; - const addRowInTable = await request(app.getHttpServer()) - .get( - `/table/row/${connections.firstId}?tableName=${fakeTableName}&id=5`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const addRowInTableRO = JSON.parse(addRowInTable.text); - t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should throw an exception when table name passed in request is incorrect`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const fakeTableName = `${faker.lorem.words(1)}_${faker.string.uuid()}`; + const addRowInTable = await request(app.getHttpServer()) + .get(`/table/row/${connections.firstId}?tableName=${fakeTableName}&id=5`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addRowInTableRO = JSON.parse(addRowInTable.text); + t.is(addRowInTableRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); //****************************** TABLE LOGS CONTROLLER TESTS ******************************// -currentTest = "GET /logs/:slug"; - -test.serial( - `${currentTest} should return all found logs in connection'`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const randomName = faker.person.firstName(); - const randomEmail = faker.internet.email(); - const created_at = new Date(); - const updated_at = new Date(); - const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .send({ - [firstTableInfo.testTableColumnName]: randomName, - [firstTableInfo.testTableSecondColumnName]: randomEmail, - created_at: created_at, - updated_at: updated_at, - }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(addRowInTable.status, 201); +currentTest = 'GET /logs/:slug'; - const getTableLogs = await request(app.getHttpServer()) - .get(`/logs/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getRowInTableRO = JSON.parse(getTableLogs.text); +test.serial(`${currentTest} should return all found logs in connection'`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const randomName = faker.person.firstName(); + const randomEmail = faker.internet.email(); + const created_at = new Date(); + const updated_at = new Date(); + const addRowInTable = await request(app.getHttpServer()) + .post(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .send({ + [firstTableInfo.testTableColumnName]: randomName, + [firstTableInfo.testTableSecondColumnName]: randomEmail, + created_at: created_at, + updated_at: updated_at, + }) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(addRowInTable.status, 201); - t.is(getRowInTableRO.logs.length, 1); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "table_name"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "received_data"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "old_data"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "cognitoUserName"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "email"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "operationType"), true); - t.is( - Object.hasOwn(getRowInTableRO.logs[0], "operationStatusResult"), - true, - ); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "createdAt"), true); - t.is(Object.hasOwn(getRowInTableRO.logs[0], "connection_id"), true); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const getTableLogs = await request(app.getHttpServer()) + .get(`/logs/${connections.firstId}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getRowInTableRO = JSON.parse(getTableLogs.text); + + t.is(getRowInTableRO.logs.length, 1); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'table_name'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'received_data'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'old_data'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'cognitoUserName'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'email'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'operationType'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'operationStatusResult'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'createdAt'), true); + t.is(Object.hasOwn(getRowInTableRO.logs[0], 'connection_id'), true); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should not return all found logs in connection, when table audit is disabled in connection'`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -2535,52 +2135,46 @@ test.serial( const created_at = new Date(); const updated_at = new Date(); - const updateConnection = - mockFactory.generateConnectionToTestPostgresDBInDocker(); + const updateConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); const updateConnectionResponse = await request(app.getHttpServer()) .put(`/connection/${connections.firstId}`) .send(updateConnection) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(updateConnectionResponse.status, 200); - const newConnectionProperties = - mockFactory.generateConnectionPropertiesUserExcluded(null, false); + const newConnectionProperties = mockFactory.generateConnectionPropertiesUserExcluded(null, false); - const createConnectionPropertiesResponse = await request( - app.getHttpServer(), - ) + const createConnectionPropertiesResponse = await request(app.getHttpServer()) .post(`/connection/properties/${connections.firstId}`) .send(newConnectionProperties) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createConnectionPropertiesResponse.status, 201); const addRowInTable = await request(app.getHttpServer()) - .post( - `/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) + .post(`/table/row/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) .send({ [firstTableInfo.testTableColumnName]: randomName, [firstTableInfo.testTableSecondColumnName]: randomEmail, created_at: created_at, updated_at: updated_at, }) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(addRowInTable.status, 201); const getTableLogs = await request(app.getHttpServer()) .get(`/logs/${connections.firstId}`) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getRowInTableRO = JSON.parse(getTableLogs.text); t.is(getRowInTableRO.logs.length, 0); @@ -2593,49 +2187,13 @@ test.serial( //****************************** TABLE SETTINGS CONTROLLER TESTS ******************************// -currentTest = "GET /settings/"; +currentTest = 'GET /settings/'; test.serial( `${currentTest} should exception ${Messages.DONT_HAVE_PERMISSIONS} when table settings was not created`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const getTableSettings = await request(app.getHttpServer()) - .get( - `/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getTableSettingsRO = JSON.parse(getTableSettings.text); - t.is(getTableSettings.status, 403); - t.is(getTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} 'should should throw exception ${Messages.DONT_HAVE_PERMISSIONS}`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -2644,36 +2202,11 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - ['id'], - [firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); - const getTableSettings = await request(app.getHttpServer()) - .get( - `/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .get(`/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); const getTableSettingsRO = JSON.parse(getTableSettings.text); t.is(getTableSettings.status, 403); t.is(getTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); @@ -2684,73 +2217,57 @@ test.serial( }, ); -test.serial( - `${currentTest} should throw an exception when you try get settings in connection where you do not have permission`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(createTableSettingsResponse.status, 201); +test.serial(`${currentTest} 'should should throw exception ${Messages.DONT_HAVE_PERMISSIONS}`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const getTableSettings = await request(app.getHttpServer()) - .get( - `/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getTableSettingsRO = JSON.parse(getTableSettings.text); - t.is(getTableSettings.status, 403); - t.is(getTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + ['id'], + [firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); -currentTest = "POST /settings/"; + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const getTableSettings = await request(app.getHttpServer()) + .get(`/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getTableSettingsRO = JSON.parse(getTableSettings.text); + t.is(getTableSettings.status, 403); + t.is(getTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( - `${currentTest} should throw an exception do not have permission`, + `${currentTest} should throw an exception when you try get settings in connection where you do not have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -2760,31 +2277,35 @@ test.serial( users: { adminUserToken, simpleUserToken }, } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - 'users', - ['id'], - ['email'], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`, - ) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) .send(createTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 403); - t.is( - JSON.parse(createTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(createTableSettingsResponse.status, 201); + + const getTableSettings = await request(app.getHttpServer()) + .get(`/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getTableSettingsRO = JSON.parse(getTableSettings.text); + t.is(getTableSettings.status, 403); + t.is(getTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -2792,14 +2313,51 @@ test.serial( }, ); +currentTest = 'POST /settings/'; + +test.serial(`${currentTest} should throw an exception do not have permission`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + 'users', + ['id'], + ['email'], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`) + .send(createTableSettingsDTO) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 403); + t.is(JSON.parse(createTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); + test.serial( `${currentTest} should throw an exception when you try create settings in connection where you do not have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -2809,31 +2367,27 @@ test.serial( users: { adminUserToken, simpleUserToken }, } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}`, - ) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}`) .send(createTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createTableSettingsResponse.status, 403); - const createTableSettingsRO = JSON.parse( - createTableSettingsResponse.text, - ); + const createTableSettingsRO = JSON.parse(createTableSettingsResponse.text); t.is(createTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); @@ -2842,133 +2396,118 @@ test.serial( }, ); -currentTest = "PUT /settings/"; +currentTest = 'PUT /settings/'; test.serial(`${currentTest} should throw an exception do not have permission`, async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - ['id'], - [firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + ['id'], + [firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); - const updateTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - [firstTableInfo.testTableSecondColumnName], - ['id'], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const updateTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + [firstTableInfo.testTableSecondColumnName], + ['id'], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); - const updateTableSettingsResponse = await request(app.getHttpServer()) - .put( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`, - ) - .send(updateTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(updateTableSettingsResponse.status, 403); - t.is( - JSON.parse(updateTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const updateTableSettingsResponse = await request(app.getHttpServer()) + .put(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}}`) + .send(updateTableSettingsDTO) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(updateTableSettingsResponse.status, 403); + t.is(JSON.parse(updateTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( - `${currentTest} should throw an exception when you try update settings in connection where you do not have permission`, - async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + `${currentTest} should throw an exception when you try update settings in connection where you do not have permission`, + async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(createTableSettingsResponse.status, 201); - const updateTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - [firstTableInfo.testTableSecondColumnName], - ['id'], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); + const updateTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + [firstTableInfo.testTableSecondColumnName], + ['id'], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); const updateTableSettingsResponse = await request(app.getHttpServer()) - .put( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}}`, - ) + .put(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}}}`) .send(updateTableSettingsDTO) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); t.is(updateTableSettingsResponse.status, 403); - t.is( - JSON.parse(updateTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); + t.is(JSON.parse(updateTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -2976,127 +2515,58 @@ test.serial( }, ); -currentTest = "DELETE /settings/"; +currentTest = 'DELETE /settings/'; test.serial(`${currentTest} should return array without deleted table settings`, async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.firstId, - firstTableInfo.testTableName, - ['id'], - [firstTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); - - const deleteTableSettingsResponse = await request(app.getHttpServer()) - .delete( - `/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - - t.is(deleteTableSettingsResponse.status, 403); - t.is( - JSON.parse(deleteTableSettingsResponse.text).message, - Messages.DONT_HAVE_PERMISSIONS, - ); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -test.serial( - `${currentTest} should throw an exception when you try delete settings in connection where you do not have permission`, - async (t) => { - try { - const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; - const createTableSettingsDTO = mockFactory.generateTableSettings( - connections.secondId, - secondTableInfo.testTableName, - ['id'], - [secondTableInfo.testTableSecondColumnName], - ['updated_at'], - ['created_at'], - undefined, - undefined, - undefined, - ); - - const createTableSettingsResponse = await request(app.getHttpServer()) - .post( - `/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .send(createTableSettingsDTO) - .set("Cookie", adminUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - t.is(createTableSettingsResponse.status, 201); - - const deleteTableSettingsResponse = await request(app.getHttpServer()) - .delete( - `/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const deleteTableSettingsRO = JSON.parse( - deleteTableSettingsResponse.text, - ); - t.is(deleteTableSettingsResponse.status, 403); - t.is(deleteTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); - -//****************************** TABLE WIDGETS CONTROLLER TESTS ******************************// + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.firstId, + firstTableInfo.testTableName, + ['id'], + [firstTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); -currentTest = "GET /widgets/:slug"; + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const deleteTableSettingsResponse = await request(app.getHttpServer()) + .delete(`/settings/?connectionId=${connections.firstId}&tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + t.is(deleteTableSettingsResponse.status, 403); + t.is(JSON.parse(deleteTableSettingsResponse.text).message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( - `${currentTest} should return empty widgets array when widgets not created`, + `${currentTest} should throw an exception when you try delete settings in connection where you do not have permission`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -3105,16 +2575,34 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const getTableWidgets = await request(app.getHttpServer()) - .get( - `/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Cookie", simpleUserToken) - .set("Content-Type", "application/json") - .set("Accept", "application/json"); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(getTableWidgets.status, 403); - t.is(getTableWidgetsRO.message, Messages.DONT_HAVE_PERMISSIONS); + const createTableSettingsDTO = mockFactory.generateTableSettings( + connections.secondId, + secondTableInfo.testTableName, + ['id'], + [secondTableInfo.testTableSecondColumnName], + ['updated_at'], + ['created_at'], + undefined, + undefined, + undefined, + ); + + const createTableSettingsResponse = await request(app.getHttpServer()) + .post(`/settings?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) + .send(createTableSettingsDTO) + .set('Cookie', adminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + t.is(createTableSettingsResponse.status, 201); + + const deleteTableSettingsResponse = await request(app.getHttpServer()) + .delete(`/settings/?connectionId=${connections.secondId}&tableName=${secondTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const deleteTableSettingsRO = JSON.parse(deleteTableSettingsResponse.text); + t.is(deleteTableSettingsResponse.status, 403); + t.is(deleteTableSettingsRO.message, Messages.DONT_HAVE_PERMISSIONS); } catch (e) { console.error(e); throw e; @@ -3122,96 +2610,97 @@ test.serial( }, ); -test.serial( - `${currentTest} should return array of table widgets for table`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +//****************************** TABLE WIDGETS CONTROLLER TESTS ******************************// - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); - const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", adminUserToken) - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 201); - t.is(typeof createTableWidgetRO, "object"); - t.is(createTableWidgetRO.length, 2); - t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); - t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); - t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); +currentTest = 'GET /widgets/:slug'; - const getTableWidgets = await request(app.getHttpServer()) - .get( - `/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - t.is(getTableWidgets.status, 403); - const getTableWidgetsRO = JSON.parse(getTableWidgets.text); - t.is(getTableWidgetsRO.message, Messages.DONT_HAVE_PERMISSIONS); +test.serial(`${currentTest} should return empty widgets array when widgets not created`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Cookie', simpleUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(getTableWidgets.status, 403); + t.is(getTableWidgetsRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); - const getTableStructureResponse = await request(app.getHttpServer()) - .get( - `/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - t.is(getTableStructureResponse.status, 200); - const getTableStructureRO = JSON.parse(getTableStructureResponse.text); - t.is(Object.hasOwn(getTableStructureRO, "table_widgets"), true); - t.is(getTableStructureRO.table_widgets.length, 2); - t.is( - getTableStructureRO.table_widgets[0].field_name, - newTableWidgets[0].field_name, - ); - t.is( - getTableStructureRO.table_widgets[1].widget_type, - newTableWidgets[1].widget_type, - ); - t.is( - compareTableWidgetsArrays( - getTableStructureRO.table_widgets, - newTableWidgets, - ), - true, - ); - } catch (e) { - console.error(e); - throw e; - } - }, -); +test.serial(`${currentTest} should return array of table widgets for table`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; + + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', adminUserToken) + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 201); + t.is(typeof createTableWidgetRO, 'object'); + t.is(createTableWidgetRO.length, 2); + t.is(createTableWidgetRO[0].widget_type, newTableWidgets[0].widget_type); + t.is(createTableWidgetRO[1].field_name, newTableWidgets[1].field_name); + t.is(createTableWidgetRO[0].name, newTableWidgets[0].name); + + const getTableWidgets = await request(app.getHttpServer()) + .get(`/widgets/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + t.is(getTableWidgets.status, 403); + const getTableWidgetsRO = JSON.parse(getTableWidgets.text); + t.is(getTableWidgetsRO.message, Messages.DONT_HAVE_PERMISSIONS); + + const getTableStructureResponse = await request(app.getHttpServer()) + .get(`/table/structure/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + t.is(getTableStructureResponse.status, 200); + const getTableStructureRO = JSON.parse(getTableStructureResponse.text); + t.is(Object.hasOwn(getTableStructureRO, 'table_widgets'), true); + t.is(getTableStructureRO.table_widgets.length, 2); + t.is(getTableStructureRO.table_widgets[0].field_name, newTableWidgets[0].field_name); + t.is(getTableStructureRO.table_widgets[1].widget_type, newTableWidgets[1].widget_type); + t.is(compareTableWidgetsArrays(getTableStructureRO.table_widgets, newTableWidgets), true); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception, when you try to get widgets from connection, when you do not have permissions`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -3220,31 +2709,26 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`, - ) + .post(`/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}`) .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", adminUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', adminUserToken) + .set('Accept', 'application/json'); const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 201); - t.is(typeof createTableWidgetRO, "object"); + t.is(typeof createTableWidgetRO, 'object'); t.is(createTableWidgetRO.length, 2); const getTableWidgets = await request(app.getHttpServer()) - .get( - `/widgets/${connections.secondId}?tableName=${secondTableInfo.testTableName}`, - ) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .get(`/widgets/${connections.secondId}?tableName=${secondTableInfo.testTableName}`) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); const getTableWidgetsRO = JSON.parse(getTableWidgets.text); t.is(getTableWidgets.status, 403); t.is(getTableWidgetsRO.message, Messages.DONT_HAVE_PERMISSIONS); @@ -3255,57 +2739,45 @@ test.serial( }, ); -currentTest = "POST /widget/:slug"; +currentTest = 'POST /widget/:slug'; -test.serial( - `${currentTest} should throw an exception do not have permissions`, - async (t) => { - try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); - const { - connections, - firstTableInfo, - groups, - permissions, - secondTableInfo, - users: { adminUserToken, simpleUserToken }, - } = testData; +test.serial(`${currentTest} should throw an exception do not have permissions`, async (t) => { + try { + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); + const { + connections, + firstTableInfo, + groups, + permissions, + secondTableInfo, + users: { adminUserToken, simpleUserToken }, + } = testData; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); - const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}}`, - ) - .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); - const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); - t.is(createTableWidgetResponse.status, 403); - t.is(createTableWidgetRO.message, Messages.DONT_HAVE_PERMISSIONS); - } catch (e) { - console.error(e); - throw e; - } - }, -); + const createTableWidgetResponse = await request(app.getHttpServer()) + .post(`/widget/${connections.firstId}?tableName=${firstTableInfo.testTableName}}`) + .send({ widgets: newTableWidgets }) + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); + const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); + t.is(createTableWidgetResponse.status, 403); + t.is(createTableWidgetRO.message, Messages.DONT_HAVE_PERMISSIONS); + } catch (e) { + console.error(e); + throw e; + } +}); test.serial( `${currentTest} should throw an exception, when you try add widget in connection, when you do not have permissions`, async (t) => { try { - const testData = - await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app, - ); + const testData = await createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions(app); const { connections, firstTableInfo, @@ -3314,20 +2786,17 @@ test.serial( secondTableInfo, users: { adminUserToken, simpleUserToken }, } = testData; - const newTableWidgets = - mockFactory.generateCreateWidgetDTOsArrayForUsersTable( - "id", - firstTableInfo.testTableColumnName, - ); + const newTableWidgets = mockFactory.generateCreateWidgetDTOsArrayForUsersTable( + 'id', + firstTableInfo.testTableColumnName, + ); const createTableWidgetResponse = await request(app.getHttpServer()) - .post( - `/widget/${connections.secondId}?tableName=${secondTableInfo.testTableName}`, - ) + .post(`/widget/${connections.secondId}?tableName=${secondTableInfo.testTableName}`) .send({ widgets: newTableWidgets }) - .set("Content-Type", "application/json") - .set("Cookie", simpleUserToken) - .set("Accept", "application/json"); + .set('Content-Type', 'application/json') + .set('Cookie', simpleUserToken) + .set('Accept', 'application/json'); const createTableWidgetRO = JSON.parse(createTableWidgetResponse.text); t.is(createTableWidgetResponse.status, 403); t.is(createTableWidgetRO.message, Messages.DONT_HAVE_PERMISSIONS); diff --git a/backend/test/jest-e2e.json b/backend/test/jest-e2e.json index f48b1c193..f84a4db28 100644 --- a/backend/test/jest-e2e.json +++ b/backend/test/jest-e2e.json @@ -1,9 +1,9 @@ { - "moduleFileExtensions": [".js", ".jsx", ".json", ".ts", ".tsx"], - "rootDir": "..", - "testEnvironment": "node", - "testRegex": ".e2e-spec.ts$", - "transform": { - "^.+\\.(t|j)s$": "ts-jest" - } + "moduleFileExtensions": [".js", ".jsx", ".json", ".ts", ".tsx"], + "rootDir": "..", + "testEnvironment": "node", + "testRegex": ".e2e-spec.ts$", + "transform": { + "^.+\\.(t|j)s$": "ts-jest" + } } diff --git a/backend/test/mock.factory.ts b/backend/test/mock.factory.ts index 3bef62c9c..e17b8b846 100644 --- a/backend/test/mock.factory.ts +++ b/backend/test/mock.factory.ts @@ -12,899 +12,899 @@ import { AccessLevelEnum, PermissionTypeEnum, QueryOrderingEnum, WidgetTypeEnum import { TestConstants } from './mocks/test-constants.js'; class CreateGroupDto { - title: string; - permissions?: Array; - isMain?: boolean; - users?: Array; + title: string; + permissions?: Array; + isMain?: boolean; + users?: Array; } import { CreatePersonalTableSettingsDto } from '../src/entities/table-settings/personal-table-settings/dto/create-personal-table-settings.dto.js'; export class MockFactory { - generateCognitoUserName() { - return 'a876284a-e902-11ea-adc1-0242ac120002'; - } - - generateCreateConnectionDtoToTEstDB() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Connection to Test DB'; - dto.type = 'postgres'; - dto.host = 'postgres'; - dto.port = 5432; - dto.username = 'postgres'; - dto.password = 'abc123'; - dto.database = 'postgres'; - dto.ssh = false; - return dto; - } - - generateCreateConnectionDto() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test Connection'; - dto.type = 'postgres'; - dto.host = 'nestjs_testing'; - dto.port = 5432; - dto.username = 'postgres'; - dto.password = 'postgres'; - dto.database = 'nestjs_testing'; - dto.ssh = false; - return dto; - } - - generateCreateEncryptedConnectionDto() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test Connection'; - dto.type = 'postgres'; - dto.host = 'nestjs_testing'; - dto.port = 5432; - dto.username = 'postgres'; - dto.password = 'postgres'; - dto.database = 'nestjs_testing'; - dto.ssh = false; - dto.masterEncryption = true; - return dto; - } - - generateCreateInternalConnectionDto() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test Internal Connection'; - dto.type = 'postgres'; - dto.host = 'postgres'; - dto.port = 5432; - dto.username = 'postgres'; - dto.password = 'abc123'; - dto.database = 'template1'; - dto.ssh = false; - return dto; - } - - generateCreateEncryptedInternalConnectionDto() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test Internal Connection'; - dto.type = 'postgres'; - dto.host = 'postgres'; - dto.port = 5432; - dto.username = 'postgres'; - dto.password = 'abc123'; - dto.database = 'postgres'; - dto.ssh = false; - dto.masterEncryption = true; - return dto; - } - - generateCreateConnectionDto2() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test Connection 2'; - dto.type = 'mysql'; - dto.host = 'testMySQL-e2e-testing'; - dto.port = 3306; - dto.username = 'root'; - dto.password = 'admin123'; - dto.database = 'testDB'; - dto.ssh = false; - return dto; - } - - generateConnectionToTestClickHouseDBInDocker() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to ClickHouse in Docker'; - dto.type = 'clickhouse'; - dto.host = 'clickhouse-e2e-testing'; - dto.port = 8123; - dto.username = 'default'; - dto.password = 'clickhouse_password'; - dto.database = 'testdb'; - dto.ssh = false; - return dto; - } - - generateConnectionToTestClickHouseAgent() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to agent db'; - dto.type = ConnectionTypesEnum.agent_clickhouse; - return dto; - } - - generateConnectionToTestMySQLDBInDocker() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to MySQL in Docker'; - dto.type = 'mysql'; - dto.host = 'testMySQL-e2e-testing'; - dto.port = 3306; - dto.username = 'root'; - dto.password = '123'; - dto.database = 'testDB'; - dto.ssh = false; - return dto; - } - - generateConnectionToTestPostgresDBInDocker() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to Postgres in Docker'; - dto.type = 'postgres'; - dto.host = 'testPg-e2e-testing'; - dto.port = 5432; - dto.username = 'postgres'; - dto.password = '123'; - dto.database = 'postgres'; - dto.ssh = false; - return dto; - } - - generateConnectionToTestMongoDBInDocker() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to MongoDB in Docker'; - dto.type = 'mongodb'; - dto.host = 'test-mongo-e2e-testing'; - dto.port = 27017; - dto.database = 'admin'; - dto.username = 'root'; - dto.password = 'example'; - dto.ssh = false; - return dto; - } - - generateConnectionToTestMongoDBAgent() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to agent db'; - dto.type = ConnectionTypesEnum.agent_mongodb; - return dto; - } - - generateConnectionToTestDynamoDBInDocker() { - const dto = new CreateConnectionDto(); - dto.title = 'Test connection to DynamoDB in Docker'; - dto.type = ConnectionTypesEnum.dynamodb; - dto.host = 'http://test-dynamodb-e2e-testing:8000'; - dto.username = 'SuperSecretAwsAccessKey'; - dto.password = 'SuperSecretAwsSecret'; - return dto; - } - - generateEncryptedConnectionToTestPostgresDBInDocker() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to Postgres in Docker'; - dto.type = 'postgres'; - dto.host = 'testPg-e2e-testing'; - dto.port = 5432; - dto.username = 'postgres'; - dto.password = '123'; - dto.database = 'postgres'; - dto.masterEncryption = true; - dto.ssh = false; - return dto; - } - - generateConnectionToTestPostgresDBWithSchemaInDocker() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to Postgres in Docker'; - dto.type = 'postgres'; - dto.host = 'testPg-e2e-testing'; - dto.port = 5432; - dto.username = 'postgres'; - dto.password = '123'; - dto.database = 'postgres'; - dto.schema = 'test_schema'; - dto.ssh = false; - return dto; - } - - generateConnectionToTestMsSQlDBInDocker() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to MSSQL in Docker'; - dto.type = 'mssql'; - dto.host = 'mssql-e2e-testing'; - dto.port = 1433; - dto.username = 'sa'; - dto.password = 'yNuXf@6T#BgoQ%U6knMp'; - dto.database = 'TempDB'; - dto.ssh = false; - return dto; - } - - generateConnectionToTestSchemaMsSQlDBInDocker() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to MSSQL in Docker'; - dto.type = 'mssql'; - dto.host = 'mssql-e2e-testing'; - dto.port = 1433; - dto.username = 'sa'; - dto.password = 'yNuXf@6T#BgoQ%U6knMp'; - dto.database = 'TempDB'; - dto.schema = 'test_schema'; - dto.ssh = false; - return dto; - } - - generateConnectionToTestOracleDBInDocker() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to Oracle on localhost'; - dto.type = 'oracledb'; - dto.host = 'test-oracle-e2e-testing'; - dto.port = 1521; - dto.username = 'SYSTEM'; - dto.sid = 'XE'; - dto.password = '12345'; - dto.database = 'XEPDB1'; - dto.ssh = false; - return dto; - } - - generateConnectionToSchemaOracleDBInDocker() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to Oracle on localhost'; - dto.type = 'oracledb'; - dto.host = 'test-oracle-e2e-testing'; - dto.port = 1521; - dto.username = 'SYSTEM'; - dto.sid = 'XE'; - dto.password = '12345'; - dto.database = 'XEPDB1'; - dto.schema = 'SYSTEM'; - dto.ssh = false; - return dto; - } - - generateConnectionToTestDbIbmDb2() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to cli db ibm db2'; - dto.type = ConnectionTypesEnum.ibmdb2; - dto.host = 'test-ibm-db2-e2e-testing'; - dto.port = 50000; - dto.username = 'db2inst1'; - dto.password = 'password'; - dto.database = 'testdb'; - dto.schema = 'SCHEMA_NAME'; - dto.ssh = false; - return dto; - } - - generateConnectionToTestElasticsearchInDocker() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to Elasticsearch in Docker'; - dto.type = 'elasticsearch'; - dto.host = 'test-elasticsearch-e2e-testing'; - dto.password = 'SuperSecretElasticPassword'; - dto.port = 9200; - dto.username = 'elastic'; - dto.ssh = false; - return dto; - } - - generateConnectionToTestCassandraInDocker() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to Cassandra in Docker'; - dto.type = 'cassandra'; - dto.host = 'test-cassandra-e2e-testing'; - dto.port = 9042; - dto.username = 'cassandra'; - dto.password = 'cassandra'; - dto.database = 'testdb'; - dto.dataCenter = 'datacenter1'; - dto.ssh = false; - return dto; - } - - generateConnectionToTestCassandraAgent() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to agent db'; - dto.type = ConnectionTypesEnum.agent_cassandra; - return dto; - } - - generateConnectionToTestRedisInDocker() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to Redis in Docker'; - dto.type = ConnectionTypesEnum.redis; - dto.host = 'test-redis-e2e-testing'; - dto.port = 6379; - dto.password = 'SuperSecretRedisPassword'; - dto.ssh = false; - return dto; - } - - generateConnectionToTestRedisAgent() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to redis agent db'; - dto.type = ConnectionTypesEnum.agent_redis; - return dto; - } - - generateKnexConfigAgentTests(db_type = 'postgres') { - switch (db_type) { - case 'postgres': - return this.generateConnectionToTestPostgresDBInDocker(); - case 'oracledb': - return this.generateConnectionToSchemaOracleDBInDocker(); - case 'mssql': - return this.generateConnectionToTestMsSQlDBInDocker(); - case 'mysql': { - const config = this.generateConnectionToTestMySQLDBInDocker(); - config.type = 'mysql2'; - return config; - } - } - } - - generateConnectionToTestDbPostgresAgent() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to agent db'; - dto.type = ConnectionTypesEnum.agent_postgres; - return dto; - } - - generateConnectionToTestDbOracleAgent() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to agent db'; - dto.type = ConnectionTypesEnum.agent_oracledb; - return dto; - } - - generateConnectionToTestDbMysqlAgent() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to agent db'; - dto.type = ConnectionTypesEnum.agent_mysql; - return dto; - } - - generateConnectionToTestDbMssqlAgent() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to agent db'; - dto.type = ConnectionTypesEnum.agent_mssql; - return dto; - } - - generateConnectionToTestDbIbmDb2Agent() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Test connection to agent db'; - dto.type = ConnectionTypesEnum.agent_ibmdb2; - return dto; - } - - generateUpdateConnectionDto() { - const dto = new CreateConnectionDto() as any; - dto.title = 'Updated Test Connection'; - dto.type = 'postgres'; - dto.host = 'testing_nestjs'; - dto.port = 5432; - dto.username = 'admin'; - dto.password = 'abc123'; - dto.database = 'testing_nestjs'; - dto.ssh = false; - return dto; - } - - generateCreateGroupDto1() { - const dto = new CreateGroupDto(); - dto.title = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; - - return dto; - } - - generateUserPermissionsArray(groupId) { - const permissionsArr = [ - { - type: 'Table', - accessLevel: 'visibility', - tableName: 'user', - groupId: groupId, - }, - { - type: 'Table', - accessLevel: 'add', - tableName: 'user', - groupId: groupId, - }, - { - type: 'Table', - accessLevel: 'edit', - tableName: 'user', - groupId: groupId, - }, - ]; - - return permissionsArr; - } - - generateCreatePermissionDTOgroup(groupId) { - return { - type: PermissionTypeEnum.Group, - accessLevel: AccessLevelEnum.edit, - tableName: '', - groupId: groupId, - }; - } - - generateCreatePermissionDTOconnection(groupId) { - return { - type: PermissionTypeEnum.Connection, - accessLevel: AccessLevelEnum.edit, - tableName: '', - groupId: groupId, - }; - } - - generateCreatePermissionDTOtable(groupId: string, tableName: string) { - return { - type: PermissionTypeEnum.Table, - accessLevel: AccessLevelEnum.edit, - tableName: tableName, - groupId: groupId, - }; - } - - generatePermissions( - connectionId: string, - _groupId: string, - firstTableName: string, - secondTableName: string, - connectionAccessLevel: string, - groupAccessLevel: string, - ) { - return { - permissions: { - connection: { - connectionId: connectionId, - accessLevel: connectionAccessLevel, - }, - group: { - groupId: connectionId, - accessLevel: groupAccessLevel, - }, - tables: [ - { - tableName: firstTableName, - accessLevel: { - visibility: true, - readonly: false, - add: true, - delete: false, - edit: true, - }, - }, - { - tableName: secondTableName, - accessLevel: { - visibility: false, - readonly: true, - add: false, - delete: false, - edit: false, - }, - }, - ], - }, - }; - } - - generateInternalPermissions( - connectionId: string, - _groupId: string, - connectionAccessLevel: string, - groupAccessLevel: string, - ) { - const bool = () => { - return Math.random() < 0.5; - }; - const tableNames = [ - 'table_widget', - 'table', - 'mock', - 'group', - 'tableSettings', - 'tableLogs', - 'permission', - 'permission_groups_group', - 'user_groups_group', - 'user', - 'connection', - 'group_permissions_permission', - 'group_users_user', - 'customFields', - 'agent', - ]; - const tableObjects = []; - for (const name of tableNames) { - tableObjects.push({ - tableName: name, - accessLevel: { - visibility: bool(), - readonly: bool(), - add: bool(), - delete: bool(), - edit: bool(), - }, - }); - } - return { - permissions: { - connection: { - connectionId: connectionId, - accessLevel: connectionAccessLevel, - }, - group: { - groupId: connectionId, - accessLevel: groupAccessLevel, - }, - tables: tableObjects, - }, - }; - } - - // { - // id: 'e82ed355-94fd-46e5-b732-c0e8f01ccc96', - // table_name: 'capitulus_xiphias_rU6K_delectatio', - // display_name: 'test display name', - // search_fields: [ 'voluptas_adulatio' ], - // excluded_fields: [], - // identification_fields: [], - // identity_column: null, - // readonly_fields: [], - // sensitive_fields: null, - // sortable_by: [], - // autocomplete_columns: [], - // columns_view: null, - // connection_id: 'k7N6nja2', - // can_add: true, - // can_delete: true, - // can_update: true, - // icon: null, - // allow_csv_export: true, - // allow_csv_import: true - // } - - generateTableSettings( - connectionId: string, - tableName: string, - searchedFields: Array, - excludedFields: Array, - // listFields: Array, - // listPerPage = 3, - // ordering: QueryOrderingEnum, - // orderingField: string, - readonlyFields: Array, - sortableBy: Array, - autocompleteColumns: Array, - identification_fields: Array, - identity_column: string, - allow_csv_import = true, - allow_csv_export = true, - ) { - /*eslint-disable*/ - return { - connection_id: connectionId, - table_name: tableName, - display_name: 'test display name', - search_fields: searchedFields, - excluded_fields: excludedFields, - readonly_fields: readonlyFields, - sortable_by: sortableBy, - autocomplete_columns: autocompleteColumns, - identification_fields: identification_fields, - identity_column: identity_column, - allow_csv_import: allow_csv_import, - allow_csv_export: allow_csv_export, - } as any; - /*eslint-enable*/ - } - - generatePersonalTableSettingsDto( - list_fields: Array, - list_per_page = 3, - ordering: QueryOrderingEnum, - ordering_field: string, - columns_view? : Array, - original_names: boolean = true, - ): CreatePersonalTableSettingsDto { - return { - columns_view, - list_fields, - list_per_page, - ordering, - ordering_field, - original_names, - }; - } - - generateTableSettingsWithoutTypes( - connectionId: any, - tableName: any, - searchedFields: any, - excludedFields: any, - // listFields: any, - // listPerPage: any, - // ordering: any, - // orderingField: any, - readonlyFields: any, - sortebleBy: any, - autocompleteColumns: any, - ) { - /*eslint-disable*/ - return { - connection_id: connectionId, - table_name: tableName, - display_name: 'test display name', - search_fields: searchedFields, - excluded_fields: excludedFields, - readonly_fields: readonlyFields, - sortable_by: sortebleBy, - autocomplete_columns: autocompleteColumns, - }; - /*eslint-enable*/ - } - - static getMockRequest(): IRequestWithCognitoInfo { - return { - arrayBuffer(): Promise { - return Promise.resolve(undefined); - }, - blob(): Promise { - return Promise.resolve(undefined); - }, - body: undefined, - bodyUsed: false, - cache: undefined, - clone(): Request { - return undefined; - }, - credentials: undefined, - destination: undefined, - formData(): Promise { - return Promise.resolve(undefined); - }, - - headers: {} as any, - integrity: '', - isHistoryNavigation: false, - isReloadNavigation: false, - json(): Promise { - return Promise.resolve(undefined); - }, - keepalive: false, - method: '', - mode: undefined, - redirect: undefined, - referrer: '', - referrerPolicy: undefined, - signal: undefined, - text(): Promise { - return Promise.resolve(''); - }, - url: '', - decoded: { - /* eslint-disable */ - at_hash: undefined, - sub: '87cdc6c3-ed8d-4b7c-890f-3ccc16b22c7f', - aud: undefined, - email_verified: undefined, - event_id: undefined, - token_use: undefined, - auth_time: undefined, - iss: undefined, - 'cognito:username': '87cdc6c3-ed8d-4b7c-890f-3ccc16b22c7f', - exp: undefined, - iat: undefined, - email: undefined, - /* eslint-enable */ - }, - } as any; - } - - generateCustomFieldForConnectionTable(fieldNameId: string, fieldNameTitle: string) { - return { - type: 'AA:Link', - template_string: `https//?connectionId={{${fieldNameId}}}&connectionTitle={{${fieldNameTitle}}}`, - text: 'Go To', - }; - } - - generateCustomFieldForUsersTable(fieldNameId: string, fieldNameTitle: string) { - return { - type: 'AA:Link', - template_string: `https//?id={{${fieldNameId}}}&email={{${fieldNameTitle}}}`, - text: 'Go To', - }; - } - - generateCreateWidgetDTOForConnectionTable() { - const newWidgetDTO = new CreateTableWidgetDto(); - /* eslint-disable */ - newWidgetDTO.field_name = 'id'; - newWidgetDTO.widget_type = WidgetTypeEnum.Password; - newWidgetDTO.widget_params = JSON.stringify({ a: '*', b: '+', c: '#', encrypt: false }); - newWidgetDTO.name = 'new widget'; - newWidgetDTO.description = 'test widget'; - /* eslint-enable */ - return newWidgetDTO; - } - - generateCreateWidgetDTOsArrayForConnectionTable() { - const widgets = []; - const newWidgetDTO = new CreateTableWidgetDto(); - /* eslint-disable */ - newWidgetDTO.field_name = 'database'; - newWidgetDTO.widget_type = WidgetTypeEnum.Password; - newWidgetDTO.widget_params = json5.stringify({ a: '*', b: '+', c: '#', encrypt: false }); - newWidgetDTO.name = 'new widget'; - newWidgetDTO.description = 'test widget'; - const newWidgetDTO2 = new CreateTableWidgetDto(); - newWidgetDTO2.field_name = 'id'; - newWidgetDTO2.widget_type = WidgetTypeEnum.Password; - newWidgetDTO2.widget_params = json5.stringify({ a: '&', b: '!!', c: '||', encrypt: false }); - newWidgetDTO2.name = 'new widget'; - newWidgetDTO2.description = 'test 2 widget'; - /* eslint-enable */ - - widgets.push(newWidgetDTO, newWidgetDTO2); - return widgets; - } - - generateCreateWidgetDTOsArrayForUsersTable(firstFieldName = 'id', secondFieldName = 'email') { - const widgets = []; - const newWidgetDTO = new CreateTableWidgetDto(); - /* eslint-disable */ - newWidgetDTO.field_name = secondFieldName; - newWidgetDTO.widget_type = WidgetTypeEnum.Password; - newWidgetDTO.widget_params = JSON.stringify({ a: '*', b: '+', c: '#', encrypt: false }); - newWidgetDTO.name = 'new widget'; - newWidgetDTO.description = 'test widget'; - const newWidgetDTO2 = new CreateTableWidgetDto(); - newWidgetDTO2.field_name = firstFieldName; - newWidgetDTO2.widget_type = WidgetTypeEnum.Password; - newWidgetDTO2.widget_params = JSON.stringify({ a: '&', b: '!!', c: '||', encrypt: false }); - newWidgetDTO2.name = 'new widget'; - newWidgetDTO2.description = 'test 2 widget'; - /* eslint-enable */ - - widgets.push(newWidgetDTO, newWidgetDTO2); - return widgets; - } - - generateUpdateWidgetDTOsArrayForConnectionTable() { - const widgets = []; - const newWidgetDTO = new CreateTableWidgetDto(); - /* eslint-disable */ - newWidgetDTO.field_name = 'database'; - newWidgetDTO.widget_type = WidgetTypeEnum.Password; - newWidgetDTO.widget_params = json5.stringify({ a: '&', b: '+', c: '#', encrypt: false }); - newWidgetDTO.name = 'new updated widget'; - newWidgetDTO.description = 'updated test widget'; - const newWidgetDTO2 = new CreateTableWidgetDto(); - newWidgetDTO2.field_name = 'id'; - newWidgetDTO2.widget_type = WidgetTypeEnum.Password; - newWidgetDTO2.widget_params = json5.stringify({ a: '-', b: '!!', c: '||', encrypt: false }); - newWidgetDTO2.name = 'new updated widget'; - newWidgetDTO2.description = 'updated test 2 widget'; - /* eslint-enable */ - - widgets.push(newWidgetDTO, newWidgetDTO2); - return widgets; - } - - generateUpdateWidgetDTOsArrayForUsersTable() { - const widgets = []; - const newWidgetDTO = new CreateTableWidgetDto(); - /* eslint-disable */ - newWidgetDTO.field_name = 'email'; - newWidgetDTO.widget_type = WidgetTypeEnum.Password; - newWidgetDTO.widget_params = JSON.stringify({ a: '&', b: '+', c: '#', encrypt: false }); - newWidgetDTO.name = 'new updated widget'; - newWidgetDTO.description = 'updated test widget'; - const newWidgetDTO2 = new CreateTableWidgetDto(); - newWidgetDTO2.field_name = 'id'; - newWidgetDTO2.widget_type = WidgetTypeEnum.Password; - newWidgetDTO2.widget_params = JSON.stringify({ a: '-', b: '!!', c: '||', encrypt: false }); - newWidgetDTO2.name = 'new updated widget'; - newWidgetDTO2.description = 'updated test 2 widget'; - /* eslint-enable */ - - widgets.push(newWidgetDTO, newWidgetDTO2); - return widgets; - } - - public static getDecodedInfo(req: any) { - const authHeaders = req.headers.authorization; - const token = (authHeaders as string)?.split(' ')[1]; - if (!token) { - const decoded = { - sub: 'a876284a-e902-11ea-adc1-0242ac120002', - }; - req.decoded = decoded; - return req; - } - const secret = 'ahalai-mahalai'; - const decoded = jwt.verify(token, secret); - req.decoded = decoded; - return req; - } - - public static generateFirstTestUserToken( - name = TestConstants.FIRST_TEST_USER.name, - sub = TestConstants.FIRST_TEST_USER.sub, - email = TestConstants.FIRST_TEST_USER.email, - ) { - return MockFactory.generateJWT({ sub, name, email }); - } - - public static generateSecondTestUserToken( - name = TestConstants.SECOND_TEST_USER.name, - sub = TestConstants.SECOND_TEST_USER.sub, - email = TestConstants.SECOND_TEST_USER.email, - ) { - return MockFactory.generateJWT({ sub, name, email }); - } - - public static generateThirdUserToken( - name = TestConstants.THIRD_TEST_USER.name, - sub = TestConstants.THIRD_TEST_USER.sub, - email = TestConstants.THIRD_TEST_USER.email, - ) { - return MockFactory.generateJWT({ sub, name, email }); - } - - private static generateJWT(user) { - const today = new Date(); - const exp = new Date(today); - exp.setDate(today.getDate() + 60); - const secret = 'ahalai-mahalai'; - return jwt.sign( - { - sub: user.sub, - username: user.username, - email: user.email, - exp: exp.getTime() / 1000, - }, - secret, - ); - } - - public static generateCreateGroupDtoWithRandomTitle(words = 1) { - const dto = new CreateGroupDto(); - dto.title = faker.lorem.words(words); - return dto; - } - - public generateConnectionPropertiesUserExcluded( - tableName: string = null, - tables_audit = true, - ): CreateConnectionPropertiesDto { - tableName = tableName || 'users'; - return { - hidden_tables: [tableName], - logo_url: faker.internet.url(), - primary_color: faker.color.rgb(), - secondary_color: faker.color.rgb(), - hostname: faker.internet.url(), - company_name: faker.company.name(), - tables_audit: tables_audit, - human_readable_table_names: faker.datatype.boolean(), - allow_ai_requests: faker.datatype.boolean(), - default_showing_table: null, - table_categories: null, - }; - } - - public generateNewTableAction(): TableActionEntity | CreateTableActionDTO { - const newTableAction = new TableActionEntity(); - newTableAction.url = faker.internet.url(); - return newTableAction; - } + generateCognitoUserName() { + return 'a876284a-e902-11ea-adc1-0242ac120002'; + } + + generateCreateConnectionDtoToTEstDB() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Connection to Test DB'; + dto.type = 'postgres'; + dto.host = 'postgres'; + dto.port = 5432; + dto.username = 'postgres'; + dto.password = 'abc123'; + dto.database = 'postgres'; + dto.ssh = false; + return dto; + } + + generateCreateConnectionDto() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test Connection'; + dto.type = 'postgres'; + dto.host = 'nestjs_testing'; + dto.port = 5432; + dto.username = 'postgres'; + dto.password = 'postgres'; + dto.database = 'nestjs_testing'; + dto.ssh = false; + return dto; + } + + generateCreateEncryptedConnectionDto() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test Connection'; + dto.type = 'postgres'; + dto.host = 'nestjs_testing'; + dto.port = 5432; + dto.username = 'postgres'; + dto.password = 'postgres'; + dto.database = 'nestjs_testing'; + dto.ssh = false; + dto.masterEncryption = true; + return dto; + } + + generateCreateInternalConnectionDto() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test Internal Connection'; + dto.type = 'postgres'; + dto.host = 'postgres'; + dto.port = 5432; + dto.username = 'postgres'; + dto.password = 'abc123'; + dto.database = 'template1'; + dto.ssh = false; + return dto; + } + + generateCreateEncryptedInternalConnectionDto() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test Internal Connection'; + dto.type = 'postgres'; + dto.host = 'postgres'; + dto.port = 5432; + dto.username = 'postgres'; + dto.password = 'abc123'; + dto.database = 'postgres'; + dto.ssh = false; + dto.masterEncryption = true; + return dto; + } + + generateCreateConnectionDto2() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test Connection 2'; + dto.type = 'mysql'; + dto.host = 'testMySQL-e2e-testing'; + dto.port = 3306; + dto.username = 'root'; + dto.password = 'admin123'; + dto.database = 'testDB'; + dto.ssh = false; + return dto; + } + + generateConnectionToTestClickHouseDBInDocker() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to ClickHouse in Docker'; + dto.type = 'clickhouse'; + dto.host = 'clickhouse-e2e-testing'; + dto.port = 8123; + dto.username = 'default'; + dto.password = 'clickhouse_password'; + dto.database = 'testdb'; + dto.ssh = false; + return dto; + } + + generateConnectionToTestClickHouseAgent() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to agent db'; + dto.type = ConnectionTypesEnum.agent_clickhouse; + return dto; + } + + generateConnectionToTestMySQLDBInDocker() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to MySQL in Docker'; + dto.type = 'mysql'; + dto.host = 'testMySQL-e2e-testing'; + dto.port = 3306; + dto.username = 'root'; + dto.password = '123'; + dto.database = 'testDB'; + dto.ssh = false; + return dto; + } + + generateConnectionToTestPostgresDBInDocker() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to Postgres in Docker'; + dto.type = 'postgres'; + dto.host = 'testPg-e2e-testing'; + dto.port = 5432; + dto.username = 'postgres'; + dto.password = '123'; + dto.database = 'postgres'; + dto.ssh = false; + return dto; + } + + generateConnectionToTestMongoDBInDocker() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to MongoDB in Docker'; + dto.type = 'mongodb'; + dto.host = 'test-mongo-e2e-testing'; + dto.port = 27017; + dto.database = 'admin'; + dto.username = 'root'; + dto.password = 'example'; + dto.ssh = false; + return dto; + } + + generateConnectionToTestMongoDBAgent() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to agent db'; + dto.type = ConnectionTypesEnum.agent_mongodb; + return dto; + } + + generateConnectionToTestDynamoDBInDocker() { + const dto = new CreateConnectionDto(); + dto.title = 'Test connection to DynamoDB in Docker'; + dto.type = ConnectionTypesEnum.dynamodb; + dto.host = 'http://test-dynamodb-e2e-testing:8000'; + dto.username = 'SuperSecretAwsAccessKey'; + dto.password = 'SuperSecretAwsSecret'; + return dto; + } + + generateEncryptedConnectionToTestPostgresDBInDocker() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to Postgres in Docker'; + dto.type = 'postgres'; + dto.host = 'testPg-e2e-testing'; + dto.port = 5432; + dto.username = 'postgres'; + dto.password = '123'; + dto.database = 'postgres'; + dto.masterEncryption = true; + dto.ssh = false; + return dto; + } + + generateConnectionToTestPostgresDBWithSchemaInDocker() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to Postgres in Docker'; + dto.type = 'postgres'; + dto.host = 'testPg-e2e-testing'; + dto.port = 5432; + dto.username = 'postgres'; + dto.password = '123'; + dto.database = 'postgres'; + dto.schema = 'test_schema'; + dto.ssh = false; + return dto; + } + + generateConnectionToTestMsSQlDBInDocker() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to MSSQL in Docker'; + dto.type = 'mssql'; + dto.host = 'mssql-e2e-testing'; + dto.port = 1433; + dto.username = 'sa'; + dto.password = 'yNuXf@6T#BgoQ%U6knMp'; + dto.database = 'TempDB'; + dto.ssh = false; + return dto; + } + + generateConnectionToTestSchemaMsSQlDBInDocker() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to MSSQL in Docker'; + dto.type = 'mssql'; + dto.host = 'mssql-e2e-testing'; + dto.port = 1433; + dto.username = 'sa'; + dto.password = 'yNuXf@6T#BgoQ%U6knMp'; + dto.database = 'TempDB'; + dto.schema = 'test_schema'; + dto.ssh = false; + return dto; + } + + generateConnectionToTestOracleDBInDocker() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to Oracle on localhost'; + dto.type = 'oracledb'; + dto.host = 'test-oracle-e2e-testing'; + dto.port = 1521; + dto.username = 'SYSTEM'; + dto.sid = 'XE'; + dto.password = '12345'; + dto.database = 'XEPDB1'; + dto.ssh = false; + return dto; + } + + generateConnectionToSchemaOracleDBInDocker() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to Oracle on localhost'; + dto.type = 'oracledb'; + dto.host = 'test-oracle-e2e-testing'; + dto.port = 1521; + dto.username = 'SYSTEM'; + dto.sid = 'XE'; + dto.password = '12345'; + dto.database = 'XEPDB1'; + dto.schema = 'SYSTEM'; + dto.ssh = false; + return dto; + } + + generateConnectionToTestDbIbmDb2() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to cli db ibm db2'; + dto.type = ConnectionTypesEnum.ibmdb2; + dto.host = 'test-ibm-db2-e2e-testing'; + dto.port = 50000; + dto.username = 'db2inst1'; + dto.password = 'password'; + dto.database = 'testdb'; + dto.schema = 'SCHEMA_NAME'; + dto.ssh = false; + return dto; + } + + generateConnectionToTestElasticsearchInDocker() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to Elasticsearch in Docker'; + dto.type = 'elasticsearch'; + dto.host = 'test-elasticsearch-e2e-testing'; + dto.password = 'SuperSecretElasticPassword'; + dto.port = 9200; + dto.username = 'elastic'; + dto.ssh = false; + return dto; + } + + generateConnectionToTestCassandraInDocker() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to Cassandra in Docker'; + dto.type = 'cassandra'; + dto.host = 'test-cassandra-e2e-testing'; + dto.port = 9042; + dto.username = 'cassandra'; + dto.password = 'cassandra'; + dto.database = 'testdb'; + dto.dataCenter = 'datacenter1'; + dto.ssh = false; + return dto; + } + + generateConnectionToTestCassandraAgent() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to agent db'; + dto.type = ConnectionTypesEnum.agent_cassandra; + return dto; + } + + generateConnectionToTestRedisInDocker() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to Redis in Docker'; + dto.type = ConnectionTypesEnum.redis; + dto.host = 'test-redis-e2e-testing'; + dto.port = 6379; + dto.password = 'SuperSecretRedisPassword'; + dto.ssh = false; + return dto; + } + + generateConnectionToTestRedisAgent() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to redis agent db'; + dto.type = ConnectionTypesEnum.agent_redis; + return dto; + } + + generateKnexConfigAgentTests(db_type = 'postgres') { + switch (db_type) { + case 'postgres': + return this.generateConnectionToTestPostgresDBInDocker(); + case 'oracledb': + return this.generateConnectionToSchemaOracleDBInDocker(); + case 'mssql': + return this.generateConnectionToTestMsSQlDBInDocker(); + case 'mysql': { + const config = this.generateConnectionToTestMySQLDBInDocker(); + config.type = 'mysql2'; + return config; + } + } + } + + generateConnectionToTestDbPostgresAgent() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to agent db'; + dto.type = ConnectionTypesEnum.agent_postgres; + return dto; + } + + generateConnectionToTestDbOracleAgent() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to agent db'; + dto.type = ConnectionTypesEnum.agent_oracledb; + return dto; + } + + generateConnectionToTestDbMysqlAgent() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to agent db'; + dto.type = ConnectionTypesEnum.agent_mysql; + return dto; + } + + generateConnectionToTestDbMssqlAgent() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to agent db'; + dto.type = ConnectionTypesEnum.agent_mssql; + return dto; + } + + generateConnectionToTestDbIbmDb2Agent() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Test connection to agent db'; + dto.type = ConnectionTypesEnum.agent_ibmdb2; + return dto; + } + + generateUpdateConnectionDto() { + const dto = new CreateConnectionDto() as any; + dto.title = 'Updated Test Connection'; + dto.type = 'postgres'; + dto.host = 'testing_nestjs'; + dto.port = 5432; + dto.username = 'admin'; + dto.password = 'abc123'; + dto.database = 'testing_nestjs'; + dto.ssh = false; + return dto; + } + + generateCreateGroupDto1() { + const dto = new CreateGroupDto(); + dto.title = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; + + return dto; + } + + generateUserPermissionsArray(groupId) { + const permissionsArr = [ + { + type: 'Table', + accessLevel: 'visibility', + tableName: 'user', + groupId: groupId, + }, + { + type: 'Table', + accessLevel: 'add', + tableName: 'user', + groupId: groupId, + }, + { + type: 'Table', + accessLevel: 'edit', + tableName: 'user', + groupId: groupId, + }, + ]; + + return permissionsArr; + } + + generateCreatePermissionDTOgroup(groupId) { + return { + type: PermissionTypeEnum.Group, + accessLevel: AccessLevelEnum.edit, + tableName: '', + groupId: groupId, + }; + } + + generateCreatePermissionDTOconnection(groupId) { + return { + type: PermissionTypeEnum.Connection, + accessLevel: AccessLevelEnum.edit, + tableName: '', + groupId: groupId, + }; + } + + generateCreatePermissionDTOtable(groupId: string, tableName: string) { + return { + type: PermissionTypeEnum.Table, + accessLevel: AccessLevelEnum.edit, + tableName: tableName, + groupId: groupId, + }; + } + + generatePermissions( + connectionId: string, + _groupId: string, + firstTableName: string, + secondTableName: string, + connectionAccessLevel: string, + groupAccessLevel: string, + ) { + return { + permissions: { + connection: { + connectionId: connectionId, + accessLevel: connectionAccessLevel, + }, + group: { + groupId: connectionId, + accessLevel: groupAccessLevel, + }, + tables: [ + { + tableName: firstTableName, + accessLevel: { + visibility: true, + readonly: false, + add: true, + delete: false, + edit: true, + }, + }, + { + tableName: secondTableName, + accessLevel: { + visibility: false, + readonly: true, + add: false, + delete: false, + edit: false, + }, + }, + ], + }, + }; + } + + generateInternalPermissions( + connectionId: string, + _groupId: string, + connectionAccessLevel: string, + groupAccessLevel: string, + ) { + const bool = () => { + return Math.random() < 0.5; + }; + const tableNames = [ + 'table_widget', + 'table', + 'mock', + 'group', + 'tableSettings', + 'tableLogs', + 'permission', + 'permission_groups_group', + 'user_groups_group', + 'user', + 'connection', + 'group_permissions_permission', + 'group_users_user', + 'customFields', + 'agent', + ]; + const tableObjects = []; + for (const name of tableNames) { + tableObjects.push({ + tableName: name, + accessLevel: { + visibility: bool(), + readonly: bool(), + add: bool(), + delete: bool(), + edit: bool(), + }, + }); + } + return { + permissions: { + connection: { + connectionId: connectionId, + accessLevel: connectionAccessLevel, + }, + group: { + groupId: connectionId, + accessLevel: groupAccessLevel, + }, + tables: tableObjects, + }, + }; + } + + // { + // id: 'e82ed355-94fd-46e5-b732-c0e8f01ccc96', + // table_name: 'capitulus_xiphias_rU6K_delectatio', + // display_name: 'test display name', + // search_fields: [ 'voluptas_adulatio' ], + // excluded_fields: [], + // identification_fields: [], + // identity_column: null, + // readonly_fields: [], + // sensitive_fields: null, + // sortable_by: [], + // autocomplete_columns: [], + // columns_view: null, + // connection_id: 'k7N6nja2', + // can_add: true, + // can_delete: true, + // can_update: true, + // icon: null, + // allow_csv_export: true, + // allow_csv_import: true + // } + + generateTableSettings( + connectionId: string, + tableName: string, + searchedFields: Array, + excludedFields: Array, + // listFields: Array, + // listPerPage = 3, + // ordering: QueryOrderingEnum, + // orderingField: string, + readonlyFields: Array, + sortableBy: Array, + autocompleteColumns: Array, + identification_fields: Array, + identity_column: string, + allow_csv_import = true, + allow_csv_export = true, + ) { + /*eslint-disable*/ + return { + connection_id: connectionId, + table_name: tableName, + display_name: 'test display name', + search_fields: searchedFields, + excluded_fields: excludedFields, + readonly_fields: readonlyFields, + sortable_by: sortableBy, + autocomplete_columns: autocompleteColumns, + identification_fields: identification_fields, + identity_column: identity_column, + allow_csv_import: allow_csv_import, + allow_csv_export: allow_csv_export, + } as any; + /*eslint-enable*/ + } + + generatePersonalTableSettingsDto( + list_fields: Array, + list_per_page = 3, + ordering: QueryOrderingEnum, + ordering_field: string, + columns_view?: Array, + original_names: boolean = true, + ): CreatePersonalTableSettingsDto { + return { + columns_view, + list_fields, + list_per_page, + ordering, + ordering_field, + original_names, + }; + } + + generateTableSettingsWithoutTypes( + connectionId: any, + tableName: any, + searchedFields: any, + excludedFields: any, + // listFields: any, + // listPerPage: any, + // ordering: any, + // orderingField: any, + readonlyFields: any, + sortebleBy: any, + autocompleteColumns: any, + ) { + /*eslint-disable*/ + return { + connection_id: connectionId, + table_name: tableName, + display_name: 'test display name', + search_fields: searchedFields, + excluded_fields: excludedFields, + readonly_fields: readonlyFields, + sortable_by: sortebleBy, + autocomplete_columns: autocompleteColumns, + }; + /*eslint-enable*/ + } + + static getMockRequest(): IRequestWithCognitoInfo { + return { + arrayBuffer(): Promise { + return Promise.resolve(undefined); + }, + blob(): Promise { + return Promise.resolve(undefined); + }, + body: undefined, + bodyUsed: false, + cache: undefined, + clone(): Request { + return undefined; + }, + credentials: undefined, + destination: undefined, + formData(): Promise { + return Promise.resolve(undefined); + }, + + headers: {} as any, + integrity: '', + isHistoryNavigation: false, + isReloadNavigation: false, + json(): Promise { + return Promise.resolve(undefined); + }, + keepalive: false, + method: '', + mode: undefined, + redirect: undefined, + referrer: '', + referrerPolicy: undefined, + signal: undefined, + text(): Promise { + return Promise.resolve(''); + }, + url: '', + decoded: { + /* eslint-disable */ + at_hash: undefined, + sub: '87cdc6c3-ed8d-4b7c-890f-3ccc16b22c7f', + aud: undefined, + email_verified: undefined, + event_id: undefined, + token_use: undefined, + auth_time: undefined, + iss: undefined, + 'cognito:username': '87cdc6c3-ed8d-4b7c-890f-3ccc16b22c7f', + exp: undefined, + iat: undefined, + email: undefined, + /* eslint-enable */ + }, + } as any; + } + + generateCustomFieldForConnectionTable(fieldNameId: string, fieldNameTitle: string) { + return { + type: 'AA:Link', + template_string: `https//?connectionId={{${fieldNameId}}}&connectionTitle={{${fieldNameTitle}}}`, + text: 'Go To', + }; + } + + generateCustomFieldForUsersTable(fieldNameId: string, fieldNameTitle: string) { + return { + type: 'AA:Link', + template_string: `https//?id={{${fieldNameId}}}&email={{${fieldNameTitle}}}`, + text: 'Go To', + }; + } + + generateCreateWidgetDTOForConnectionTable() { + const newWidgetDTO = new CreateTableWidgetDto(); + /* eslint-disable */ + newWidgetDTO.field_name = 'id'; + newWidgetDTO.widget_type = WidgetTypeEnum.Password; + newWidgetDTO.widget_params = JSON.stringify({ a: '*', b: '+', c: '#', encrypt: false }); + newWidgetDTO.name = 'new widget'; + newWidgetDTO.description = 'test widget'; + /* eslint-enable */ + return newWidgetDTO; + } + + generateCreateWidgetDTOsArrayForConnectionTable() { + const widgets = []; + const newWidgetDTO = new CreateTableWidgetDto(); + /* eslint-disable */ + newWidgetDTO.field_name = 'database'; + newWidgetDTO.widget_type = WidgetTypeEnum.Password; + newWidgetDTO.widget_params = json5.stringify({ a: '*', b: '+', c: '#', encrypt: false }); + newWidgetDTO.name = 'new widget'; + newWidgetDTO.description = 'test widget'; + const newWidgetDTO2 = new CreateTableWidgetDto(); + newWidgetDTO2.field_name = 'id'; + newWidgetDTO2.widget_type = WidgetTypeEnum.Password; + newWidgetDTO2.widget_params = json5.stringify({ a: '&', b: '!!', c: '||', encrypt: false }); + newWidgetDTO2.name = 'new widget'; + newWidgetDTO2.description = 'test 2 widget'; + /* eslint-enable */ + + widgets.push(newWidgetDTO, newWidgetDTO2); + return widgets; + } + + generateCreateWidgetDTOsArrayForUsersTable(firstFieldName = 'id', secondFieldName = 'email') { + const widgets = []; + const newWidgetDTO = new CreateTableWidgetDto(); + /* eslint-disable */ + newWidgetDTO.field_name = secondFieldName; + newWidgetDTO.widget_type = WidgetTypeEnum.Password; + newWidgetDTO.widget_params = JSON.stringify({ a: '*', b: '+', c: '#', encrypt: false }); + newWidgetDTO.name = 'new widget'; + newWidgetDTO.description = 'test widget'; + const newWidgetDTO2 = new CreateTableWidgetDto(); + newWidgetDTO2.field_name = firstFieldName; + newWidgetDTO2.widget_type = WidgetTypeEnum.Password; + newWidgetDTO2.widget_params = JSON.stringify({ a: '&', b: '!!', c: '||', encrypt: false }); + newWidgetDTO2.name = 'new widget'; + newWidgetDTO2.description = 'test 2 widget'; + /* eslint-enable */ + + widgets.push(newWidgetDTO, newWidgetDTO2); + return widgets; + } + + generateUpdateWidgetDTOsArrayForConnectionTable() { + const widgets = []; + const newWidgetDTO = new CreateTableWidgetDto(); + /* eslint-disable */ + newWidgetDTO.field_name = 'database'; + newWidgetDTO.widget_type = WidgetTypeEnum.Password; + newWidgetDTO.widget_params = json5.stringify({ a: '&', b: '+', c: '#', encrypt: false }); + newWidgetDTO.name = 'new updated widget'; + newWidgetDTO.description = 'updated test widget'; + const newWidgetDTO2 = new CreateTableWidgetDto(); + newWidgetDTO2.field_name = 'id'; + newWidgetDTO2.widget_type = WidgetTypeEnum.Password; + newWidgetDTO2.widget_params = json5.stringify({ a: '-', b: '!!', c: '||', encrypt: false }); + newWidgetDTO2.name = 'new updated widget'; + newWidgetDTO2.description = 'updated test 2 widget'; + /* eslint-enable */ + + widgets.push(newWidgetDTO, newWidgetDTO2); + return widgets; + } + + generateUpdateWidgetDTOsArrayForUsersTable() { + const widgets = []; + const newWidgetDTO = new CreateTableWidgetDto(); + /* eslint-disable */ + newWidgetDTO.field_name = 'email'; + newWidgetDTO.widget_type = WidgetTypeEnum.Password; + newWidgetDTO.widget_params = JSON.stringify({ a: '&', b: '+', c: '#', encrypt: false }); + newWidgetDTO.name = 'new updated widget'; + newWidgetDTO.description = 'updated test widget'; + const newWidgetDTO2 = new CreateTableWidgetDto(); + newWidgetDTO2.field_name = 'id'; + newWidgetDTO2.widget_type = WidgetTypeEnum.Password; + newWidgetDTO2.widget_params = JSON.stringify({ a: '-', b: '!!', c: '||', encrypt: false }); + newWidgetDTO2.name = 'new updated widget'; + newWidgetDTO2.description = 'updated test 2 widget'; + /* eslint-enable */ + + widgets.push(newWidgetDTO, newWidgetDTO2); + return widgets; + } + + public static getDecodedInfo(req: any) { + const authHeaders = req.headers.authorization; + const token = (authHeaders as string)?.split(' ')[1]; + if (!token) { + const decoded = { + sub: 'a876284a-e902-11ea-adc1-0242ac120002', + }; + req.decoded = decoded; + return req; + } + const secret = 'ahalai-mahalai'; + const decoded = jwt.verify(token, secret); + req.decoded = decoded; + return req; + } + + public static generateFirstTestUserToken( + name = TestConstants.FIRST_TEST_USER.name, + sub = TestConstants.FIRST_TEST_USER.sub, + email = TestConstants.FIRST_TEST_USER.email, + ) { + return MockFactory.generateJWT({ sub, name, email }); + } + + public static generateSecondTestUserToken( + name = TestConstants.SECOND_TEST_USER.name, + sub = TestConstants.SECOND_TEST_USER.sub, + email = TestConstants.SECOND_TEST_USER.email, + ) { + return MockFactory.generateJWT({ sub, name, email }); + } + + public static generateThirdUserToken( + name = TestConstants.THIRD_TEST_USER.name, + sub = TestConstants.THIRD_TEST_USER.sub, + email = TestConstants.THIRD_TEST_USER.email, + ) { + return MockFactory.generateJWT({ sub, name, email }); + } + + private static generateJWT(user) { + const today = new Date(); + const exp = new Date(today); + exp.setDate(today.getDate() + 60); + const secret = 'ahalai-mahalai'; + return jwt.sign( + { + sub: user.sub, + username: user.username, + email: user.email, + exp: exp.getTime() / 1000, + }, + secret, + ); + } + + public static generateCreateGroupDtoWithRandomTitle(words = 1) { + const dto = new CreateGroupDto(); + dto.title = faker.lorem.words(words); + return dto; + } + + public generateConnectionPropertiesUserExcluded( + tableName: string = null, + tables_audit = true, + ): CreateConnectionPropertiesDto { + tableName = tableName || 'users'; + return { + hidden_tables: [tableName], + logo_url: faker.internet.url(), + primary_color: faker.color.rgb(), + secondary_color: faker.color.rgb(), + hostname: faker.internet.url(), + company_name: faker.company.name(), + tables_audit: tables_audit, + human_readable_table_names: faker.datatype.boolean(), + allow_ai_requests: faker.datatype.boolean(), + default_showing_table: null, + table_categories: null, + }; + } + + public generateNewTableAction(): TableActionEntity | CreateTableActionDTO { + const newTableAction = new TableActionEntity(); + newTableAction.url = faker.internet.url(); + return newTableAction; + } } diff --git a/backend/test/mocks/test-constants.ts b/backend/test/mocks/test-constants.ts index 14839a334..84f56224f 100644 --- a/backend/test/mocks/test-constants.ts +++ b/backend/test/mocks/test-constants.ts @@ -1,17 +1,17 @@ export const TestConstants = { - FIRST_TEST_USER: { - name: 'Ivan', - sub: '2a724307-3468-4929-a081-cc5eaace274d', - email: 'Ivan_Test@gmail.com', - }, - SECOND_TEST_USER: { - name: 'Nikolay', - sub: '09ded224-b6ea-4a8a-8fd6-682af5b3b8c4', - email: 'Nikolay_Test@gmail.com', - }, - THIRD_TEST_USER: { - name: 'Michail', - sub: '1b94a770-0cce-4fc0-b69b-724f07435408', - email: 'Michail_Test@gmail.com', - }, -}; \ No newline at end of file + FIRST_TEST_USER: { + name: 'Ivan', + sub: '2a724307-3468-4929-a081-cc5eaace274d', + email: 'Ivan_Test@gmail.com', + }, + SECOND_TEST_USER: { + name: 'Nikolay', + sub: '09ded224-b6ea-4a8a-8fd6-682af5b3b8c4', + email: 'Nikolay_Test@gmail.com', + }, + THIRD_TEST_USER: { + name: 'Michail', + sub: '1b94a770-0cce-4fc0-b69b-724f07435408', + email: 'Michail_Test@gmail.com', + }, +}; diff --git a/backend/test/utils/compare-table-widgets-arrays.ts b/backend/test/utils/compare-table-widgets-arrays.ts index 5379d8341..1312e5819 100644 --- a/backend/test/utils/compare-table-widgets-arrays.ts +++ b/backend/test/utils/compare-table-widgets-arrays.ts @@ -3,35 +3,35 @@ import { CreateTableWidgetDto } from '../../src/entities/widget/dto/index.js'; import { TableWidgetEntity } from '../../src/entities/widget/table-widget.entity.js'; export const compareTableWidgetsArrays = ( - arr_1: Array, - arr_2: Array, + arr_1: Array, + arr_2: Array, ): boolean => { - arr_1 = arr_1.map((el) => { - for (const elKey in el) { - if (!el[elKey]) delete el[elKey]; - if (elKey === 'id') delete el[elKey]; - if (elKey === 'widget_params') { - el[elKey] = JSON.stringify(json5.parse(el[elKey])); - } - } - return el; - }); - arr_2 = arr_2.map((el) => { - for (const elKey in el) { - if (!el[elKey]) delete el[elKey]; - if (elKey === 'id') delete el[elKey]; - if (elKey === 'widget_params') { - el[elKey] = JSON.stringify(json5.parse(el[elKey])); - } - } - return el; - }); - for (const w_1 of arr_1) { - const w_2 = arr_2[arr_2.findIndex((_) => _.field_name === w_1.field_name)]; - if (!w_2) return false; - for (const key in w_1) { - if (w_1[key] !== w_2[key]) return false; - } - } - return true; + arr_1 = arr_1.map((el) => { + for (const elKey in el) { + if (!el[elKey]) delete el[elKey]; + if (elKey === 'id') delete el[elKey]; + if (elKey === 'widget_params') { + el[elKey] = JSON.stringify(json5.parse(el[elKey])); + } + } + return el; + }); + arr_2 = arr_2.map((el) => { + for (const elKey in el) { + if (!el[elKey]) delete el[elKey]; + if (elKey === 'id') delete el[elKey]; + if (elKey === 'widget_params') { + el[elKey] = JSON.stringify(json5.parse(el[elKey])); + } + } + return el; + }); + for (const w_1 of arr_1) { + const w_2 = arr_2[arr_2.findIndex((_) => _.field_name === w_1.field_name)]; + if (!w_2) return false; + for (const key in w_1) { + if (w_1[key] !== w_2[key]) return false; + } + } + return true; }; diff --git a/backend/test/utils/create-test-table.ts b/backend/test/utils/create-test-table.ts index d0e712289..347827f95 100644 --- a/backend/test/utils/create-test-table.ts +++ b/backend/test/utils/create-test-table.ts @@ -1,9 +1,9 @@ /* eslint-disable @typescript-eslint/no-unused-vars */ -import { faker, } from '@faker-js/faker'; +import { faker } from '@faker-js/faker'; import { getRandomConstraintName, getRandomTestTableName } from './get-random-test-table-name.js'; import { getTestKnex } from './get-test-knex.js'; import ibmdb from 'ibm_db'; -import { MongoClient, } from 'mongodb'; +import { MongoClient } from 'mongodb'; import { DynamoDB, PutItemCommand, PutItemCommandInput } from '@aws-sdk/client-dynamodb'; import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb'; import { Client } from '@elastic/elasticsearch'; @@ -14,238 +14,238 @@ import { createClient as createClickHouseClient } from '@clickhouse/client'; import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/enums/connection-types-enum.js'; export async function createTestTable( - connectionParams: any, - testEntitiesSeedsCount = 42, - testSearchedUserName = 'Vasia', - withJsonField = false, - withWidgetsData = false, + connectionParams: any, + testEntitiesSeedsCount = 42, + testSearchedUserName = 'Vasia', + withJsonField = false, + withWidgetsData = false, ): Promise { - if (connectionParams.type === ConnectionTypesEnum.ibmdb2) { - return createTestTableIbmDb2(connectionParams, testEntitiesSeedsCount, testSearchedUserName); - } - - if (connectionParams.type === ConnectionTypesEnum.mongodb) { - return createTestMongoTable(connectionParams, testEntitiesSeedsCount, testSearchedUserName); - } - - if (connectionParams.type === ConnectionTypesEnum.elasticsearch) { - return createTestElasticsearchTable(connectionParams, testEntitiesSeedsCount, testSearchedUserName); - } - - if (connectionParams.type === ConnectionTypesEnum.cassandra) { - return createTestCassandraTable(connectionParams, testEntitiesSeedsCount, testSearchedUserName); - } - - if (connectionParams.type === ConnectionTypesEnum.dynamodb) { - return createTestDynamoDBTable(connectionParams, testEntitiesSeedsCount, testSearchedUserName); - } - - if (connectionParams.type === ConnectionTypesEnum.redis) { - return createTestRedisTable(connectionParams, testEntitiesSeedsCount, testSearchedUserName); - } - - if (connectionParams.type === ConnectionTypesEnum.clickhouse) { - return createTestClickHouseTable(connectionParams, testEntitiesSeedsCount, testSearchedUserName); - } - - const testTableName = getRandomTestTableName(); - const testTableColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; - const testTableSecondColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; - const connectionParamsCopy = { - ...connectionParams, - }; - if (connectionParams.type === 'mysql') { - connectionParamsCopy.type = 'mysql2'; - } - const Knex = getTestKnex(connectionParamsCopy); - // await Knex.schema.dropTableIfExists(testTableName); - await Knex.schema.createTable(testTableName, (table) => { - table.increments(); - table.string(testTableColumnName); - table.string(testTableSecondColumnName); - table.timestamps(); - }); - - if (withJsonField) { - await Knex.schema.table(testTableName, (table) => { - table.json('json_field'); - table.jsonb('jsonb_field'); - }); - } - - // telephoneColumns, - // uuidColumns, - // countryCodeColumns, - // urlColumns, - // rgbColorColumns, - // hexColorColumns, - // hslColorColumns, - // email columns already exists as some of the test columns - if (withWidgetsData) { - await Knex.schema.table(testTableName, (table) => { - table.string('telephone'); - table.string('uuid'); - table.string('countryCode'); - table.string('url'); - table.string('rgbColor'); - table.string('hexColor'); - table.string('hslColor'); - }); - } - - for (let i = 0; i < testEntitiesSeedsCount; i++) { - const widgetsDataObject: any = {}; - if (withWidgetsData) { - widgetsDataObject.telephone = faker.phone.number({ style: 'international' }); - widgetsDataObject.uuid = faker.string.uuid(); - widgetsDataObject.countryCode = faker.location.countryCode(); - widgetsDataObject.url = faker.internet.url(); - widgetsDataObject.rgbColor = faker.color.rgb(); - widgetsDataObject.hexColor = faker.color.rgb({ format: 'hex', casing: 'lower' }); - widgetsDataObject.hslColor = faker.color.hsl({ format: 'css' }); - } - if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { - await Knex(testTableName).insert({ - [testTableColumnName]: testSearchedUserName, - [testTableSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - ...widgetsDataObject, - }); - } else { - await Knex(testTableName).insert({ - [testTableColumnName]: faker.person.firstName(), - [testTableSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - ...widgetsDataObject, - }); - } - } - return { - testTableName: testTableName, - testTableColumnName: testTableColumnName, - testTableSecondColumnName: testTableSecondColumnName, - testEntitiesSeedsCount: testEntitiesSeedsCount, - }; + if (connectionParams.type === ConnectionTypesEnum.ibmdb2) { + return createTestTableIbmDb2(connectionParams, testEntitiesSeedsCount, testSearchedUserName); + } + + if (connectionParams.type === ConnectionTypesEnum.mongodb) { + return createTestMongoTable(connectionParams, testEntitiesSeedsCount, testSearchedUserName); + } + + if (connectionParams.type === ConnectionTypesEnum.elasticsearch) { + return createTestElasticsearchTable(connectionParams, testEntitiesSeedsCount, testSearchedUserName); + } + + if (connectionParams.type === ConnectionTypesEnum.cassandra) { + return createTestCassandraTable(connectionParams, testEntitiesSeedsCount, testSearchedUserName); + } + + if (connectionParams.type === ConnectionTypesEnum.dynamodb) { + return createTestDynamoDBTable(connectionParams, testEntitiesSeedsCount, testSearchedUserName); + } + + if (connectionParams.type === ConnectionTypesEnum.redis) { + return createTestRedisTable(connectionParams, testEntitiesSeedsCount, testSearchedUserName); + } + + if (connectionParams.type === ConnectionTypesEnum.clickhouse) { + return createTestClickHouseTable(connectionParams, testEntitiesSeedsCount, testSearchedUserName); + } + + const testTableName = getRandomTestTableName(); + const testTableColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; + const testTableSecondColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; + const connectionParamsCopy = { + ...connectionParams, + }; + if (connectionParams.type === 'mysql') { + connectionParamsCopy.type = 'mysql2'; + } + const Knex = getTestKnex(connectionParamsCopy); + // await Knex.schema.dropTableIfExists(testTableName); + await Knex.schema.createTable(testTableName, (table) => { + table.increments(); + table.string(testTableColumnName); + table.string(testTableSecondColumnName); + table.timestamps(); + }); + + if (withJsonField) { + await Knex.schema.table(testTableName, (table) => { + table.json('json_field'); + table.jsonb('jsonb_field'); + }); + } + + // telephoneColumns, + // uuidColumns, + // countryCodeColumns, + // urlColumns, + // rgbColorColumns, + // hexColorColumns, + // hslColorColumns, + // email columns already exists as some of the test columns + if (withWidgetsData) { + await Knex.schema.table(testTableName, (table) => { + table.string('telephone'); + table.string('uuid'); + table.string('countryCode'); + table.string('url'); + table.string('rgbColor'); + table.string('hexColor'); + table.string('hslColor'); + }); + } + + for (let i = 0; i < testEntitiesSeedsCount; i++) { + const widgetsDataObject: any = {}; + if (withWidgetsData) { + widgetsDataObject.telephone = faker.phone.number({ style: 'international' }); + widgetsDataObject.uuid = faker.string.uuid(); + widgetsDataObject.countryCode = faker.location.countryCode(); + widgetsDataObject.url = faker.internet.url(); + widgetsDataObject.rgbColor = faker.color.rgb(); + widgetsDataObject.hexColor = faker.color.rgb({ format: 'hex', casing: 'lower' }); + widgetsDataObject.hslColor = faker.color.hsl({ format: 'css' }); + } + if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { + await Knex(testTableName).insert({ + [testTableColumnName]: testSearchedUserName, + [testTableSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + ...widgetsDataObject, + }); + } else { + await Knex(testTableName).insert({ + [testTableColumnName]: faker.person.firstName(), + [testTableSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + ...widgetsDataObject, + }); + } + } + return { + testTableName: testTableName, + testTableColumnName: testTableColumnName, + testTableSecondColumnName: testTableSecondColumnName, + testEntitiesSeedsCount: testEntitiesSeedsCount, + }; } async function createTestElasticsearchTable( - connectionParams, - testEntitiesSeedsCount = 42, - testSearchedUserName = 'Vasia', + connectionParams, + testEntitiesSeedsCount = 42, + testSearchedUserName = 'Vasia', ): Promise { - const testTableName = getRandomTestTableName().toLowerCase(); - const testTableColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; - const testTableSecondColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; - const { host, port, username, password } = connectionParams; - const protocol = 'http'; - const node = `${protocol}://${host}:${port}`; - const options: any = { - node, - auth: { - username, - password, - }, - }; - const client = new Client(options); - const _response = await client.indices.create({ - index: testTableName, - }); - await client.indices.putMapping({ - index: testTableName, - dynamic: 'runtime', - properties: { - [testTableColumnName]: { - type: 'text', - }, - [testTableSecondColumnName]: { - type: 'text', - }, - }, - }); - const insertedSearchedIds: Array<{ - number: number; - _id: string; - }> = []; - for (let i = 0; i < testEntitiesSeedsCount; i++) { - if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { - const insertResult = await client.index({ - index: testTableName, - body: { - [testTableColumnName]: testSearchedUserName, - [testTableSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - age: i === 0 ? 14 : i === testEntitiesSeedsCount - 21 ? 90 : 95, - }, - }); - insertedSearchedIds.push({ - number: i, - _id: insertResult._id, - }); - } else { - const insertResult = await client.index({ - index: testTableName, - body: { - [testTableColumnName]: faker.person.firstName(), - [testTableSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - age: faker.number.int({ min: 16, max: 80 }), - }, - }); - insertedSearchedIds.push({ - number: i, - _id: insertResult._id, - }); - } - } - await client.indices.refresh({ index: testTableName }); - return { - testTableName: testTableName, - testTableColumnName: testTableColumnName, - testTableSecondColumnName: testTableSecondColumnName, - testEntitiesSeedsCount: testEntitiesSeedsCount, - insertedSearchedIds, - }; + const testTableName = getRandomTestTableName().toLowerCase(); + const testTableColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; + const testTableSecondColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; + const { host, port, username, password } = connectionParams; + const protocol = 'http'; + const node = `${protocol}://${host}:${port}`; + const options: any = { + node, + auth: { + username, + password, + }, + }; + const client = new Client(options); + const _response = await client.indices.create({ + index: testTableName, + }); + await client.indices.putMapping({ + index: testTableName, + dynamic: 'runtime', + properties: { + [testTableColumnName]: { + type: 'text', + }, + [testTableSecondColumnName]: { + type: 'text', + }, + }, + }); + const insertedSearchedIds: Array<{ + number: number; + _id: string; + }> = []; + for (let i = 0; i < testEntitiesSeedsCount; i++) { + if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { + const insertResult = await client.index({ + index: testTableName, + body: { + [testTableColumnName]: testSearchedUserName, + [testTableSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + age: i === 0 ? 14 : i === testEntitiesSeedsCount - 21 ? 90 : 95, + }, + }); + insertedSearchedIds.push({ + number: i, + _id: insertResult._id, + }); + } else { + const insertResult = await client.index({ + index: testTableName, + body: { + [testTableColumnName]: faker.person.firstName(), + [testTableSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + age: faker.number.int({ min: 16, max: 80 }), + }, + }); + insertedSearchedIds.push({ + number: i, + _id: insertResult._id, + }); + } + } + await client.indices.refresh({ index: testTableName }); + return { + testTableName: testTableName, + testTableColumnName: testTableColumnName, + testTableSecondColumnName: testTableSecondColumnName, + testEntitiesSeedsCount: testEntitiesSeedsCount, + insertedSearchedIds, + }; } async function createTestTableIbmDb2( - connectionParams: any, - testEntitiesSeedsCount = 42, - testSearchedUserName = 'Vasia', + connectionParams: any, + testEntitiesSeedsCount = 42, + testSearchedUserName = 'Vasia', ): Promise { - const testTableName = getRandomTestTableName().toUpperCase(); - const testTableColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`.replace(/[-@]/g, '').toUpperCase(); - const testTableSecondColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}` - .replace(/[-@]/g, '') - .toUpperCase(); - const connStr = `DATABASE=${connectionParams.database};HOSTNAME=${connectionParams.host};UID=${connectionParams.username};PWD=${connectionParams.password};PORT=${connectionParams.port};PROTOCOL=TCPIP`; - - const ibmDatabase = ibmdb(); - await ibmDatabase.open(connStr); - const queryCheckSchemaExists = `SELECT COUNT(*) FROM SYSCAT.SCHEMATA WHERE SCHEMANAME = '${connectionParams.schema}'`; - const schemaExists = await ibmDatabase.query(queryCheckSchemaExists); - - if (!schemaExists.length || !schemaExists[0]['1']) { - const queryCreateSchema = `CREATE SCHEMA ${connectionParams.schema}`; - try { - await ibmDatabase.query(queryCreateSchema); - } catch (error) { - console.error(`Error while creating schema: ${error}`); - console.info(`Query: ${queryCreateSchema}`); - } - } - - const queryCheckTableExists = `SELECT COUNT(*) FROM SYSCAT.TABLES WHERE TABNAME = '${testTableName}' AND TABSCHEMA = '${connectionParams.schema}'`; - const tableExists = await ibmDatabase.query(queryCheckTableExists); - - if (tableExists.length && tableExists[0]['1']) { - await ibmDatabase.query(`DROP TABLE ${connectionParams.schema}.${testTableName}`); - } - - const query = ` + const testTableName = getRandomTestTableName().toUpperCase(); + const testTableColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`.replace(/[-@]/g, '').toUpperCase(); + const testTableSecondColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}` + .replace(/[-@]/g, '') + .toUpperCase(); + const connStr = `DATABASE=${connectionParams.database};HOSTNAME=${connectionParams.host};UID=${connectionParams.username};PWD=${connectionParams.password};PORT=${connectionParams.port};PROTOCOL=TCPIP`; + + const ibmDatabase = ibmdb(); + await ibmDatabase.open(connStr); + const queryCheckSchemaExists = `SELECT COUNT(*) FROM SYSCAT.SCHEMATA WHERE SCHEMANAME = '${connectionParams.schema}'`; + const schemaExists = await ibmDatabase.query(queryCheckSchemaExists); + + if (!schemaExists.length || !schemaExists[0]['1']) { + const queryCreateSchema = `CREATE SCHEMA ${connectionParams.schema}`; + try { + await ibmDatabase.query(queryCreateSchema); + } catch (error) { + console.error(`Error while creating schema: ${error}`); + console.info(`Query: ${queryCreateSchema}`); + } + } + + const queryCheckTableExists = `SELECT COUNT(*) FROM SYSCAT.TABLES WHERE TABNAME = '${testTableName}' AND TABSCHEMA = '${connectionParams.schema}'`; + const tableExists = await ibmDatabase.query(queryCheckTableExists); + + if (tableExists.length && tableExists[0]['1']) { + await ibmDatabase.query(`DROP TABLE ${connectionParams.schema}.${testTableName}`); + } + + const query = ` CREATE TABLE ${connectionParams.schema}.${testTableName} ( id INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1), ${testTableColumnName} VARCHAR(255), @@ -255,658 +255,658 @@ async function createTestTableIbmDb2( PRIMARY KEY (id) )`; - try { - await ibmDatabase.query(query); - } catch (error) { - console.error(`Error while creating table: ${error}`); - console.info(`Query: ${query}`); - } - - for (let i = 0; i < testEntitiesSeedsCount; i++) { - if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { - await ibmDatabase.query( - `INSERT INTO ${ - connectionParams.schema - }.${testTableName} (${testTableColumnName}, ${testTableSecondColumnName}, created_at, updated_at) VALUES ('${testSearchedUserName}', '${faker.internet.email()}', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)`, - ); - } else { - await ibmDatabase.query( - `INSERT INTO ${ - connectionParams.schema - }.${testTableName} (${testTableColumnName}, ${testTableSecondColumnName}, created_at, updated_at) VALUES ('${faker.person - .firstName() - .replace(/["']/g, '')}', '${faker.internet - .email() - .replace(/["']/g, '')}', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)`, - ); - } - } - - return { - testTableName: testTableName, - testTableColumnName: testTableColumnName, - testTableSecondColumnName: testTableSecondColumnName, - testEntitiesSeedsCount: testEntitiesSeedsCount, - }; + try { + await ibmDatabase.query(query); + } catch (error) { + console.error(`Error while creating table: ${error}`); + console.info(`Query: ${query}`); + } + + for (let i = 0; i < testEntitiesSeedsCount; i++) { + if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { + await ibmDatabase.query( + `INSERT INTO ${ + connectionParams.schema + }.${testTableName} (${testTableColumnName}, ${testTableSecondColumnName}, created_at, updated_at) VALUES ('${testSearchedUserName}', '${faker.internet.email()}', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)`, + ); + } else { + await ibmDatabase.query( + `INSERT INTO ${ + connectionParams.schema + }.${testTableName} (${testTableColumnName}, ${testTableSecondColumnName}, created_at, updated_at) VALUES ('${faker.person + .firstName() + .replace(/["']/g, '')}', '${faker.internet + .email() + .replace(/["']/g, '')}', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)`, + ); + } + } + + return { + testTableName: testTableName, + testTableColumnName: testTableColumnName, + testTableSecondColumnName: testTableSecondColumnName, + testEntitiesSeedsCount: testEntitiesSeedsCount, + }; } async function createTestMongoTable( - connectionParams, - testEntitiesSeedsCount, - testSearchedUserName, + connectionParams, + testEntitiesSeedsCount, + testSearchedUserName, ): Promise { - const testTableName = getRandomTestTableName(); - const testTableColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; - const testTableSecondColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; - - const mongoConnectionString = - `mongodb://${connectionParams.username}` + - `:${connectionParams.password}` + - `@${connectionParams.host}` + - `:${connectionParams.port}` + - `/${connectionParams.database}`; - - const client = new MongoClient(mongoConnectionString); - await client.connect(); - const db = client.db(connectionParams.database); - const collection = db.collection(testTableName); - - await collection.drop(); - const insertedSearchedIds = []; - for (let i = 0; i < testEntitiesSeedsCount; i++) { - if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { - const insertionResult = await collection.insertOne({ - [testTableColumnName]: testSearchedUserName, - [testTableSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - age: i === 0 ? 14 : i === testEntitiesSeedsCount - 21 ? 90 : 95, - }); - insertedSearchedIds.push({ - number: i, - _id: insertionResult.insertedId.toHexString(), - }); - } else { - const insertionResult = await collection.insertOne({ - [testTableColumnName]: faker.person.firstName(), - [testTableSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - age: faker.number.int({ min: 16, max: 80 }), - }); - insertedSearchedIds.push({ - number: i, - _id: insertionResult.insertedId.toHexString(), - }); - } - } - return { - testTableName: testTableName, - testTableColumnName: testTableColumnName, - testTableSecondColumnName: testTableSecondColumnName, - testEntitiesSeedsCount: testEntitiesSeedsCount, - insertedSearchedIds, - }; + const testTableName = getRandomTestTableName(); + const testTableColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; + const testTableSecondColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; + + const mongoConnectionString = + `mongodb://${connectionParams.username}` + + `:${connectionParams.password}` + + `@${connectionParams.host}` + + `:${connectionParams.port}` + + `/${connectionParams.database}`; + + const client = new MongoClient(mongoConnectionString); + await client.connect(); + const db = client.db(connectionParams.database); + const collection = db.collection(testTableName); + + await collection.drop(); + const insertedSearchedIds = []; + for (let i = 0; i < testEntitiesSeedsCount; i++) { + if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { + const insertionResult = await collection.insertOne({ + [testTableColumnName]: testSearchedUserName, + [testTableSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + age: i === 0 ? 14 : i === testEntitiesSeedsCount - 21 ? 90 : 95, + }); + insertedSearchedIds.push({ + number: i, + _id: insertionResult.insertedId.toHexString(), + }); + } else { + const insertionResult = await collection.insertOne({ + [testTableColumnName]: faker.person.firstName(), + [testTableSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + age: faker.number.int({ min: 16, max: 80 }), + }); + insertedSearchedIds.push({ + number: i, + _id: insertionResult.insertedId.toHexString(), + }); + } + } + return { + testTableName: testTableName, + testTableColumnName: testTableColumnName, + testTableSecondColumnName: testTableSecondColumnName, + testEntitiesSeedsCount: testEntitiesSeedsCount, + insertedSearchedIds, + }; } export type CreatedTableInfo = { - testTableName: string; - testTableColumnName: string; - testTableSecondColumnName: string; - testEntitiesSeedsCount: number; - insertedSearchedIds?: Array<{ number: number; _id?: string; id?: string }>; + testTableName: string; + testTableColumnName: string; + testTableSecondColumnName: string; + testEntitiesSeedsCount: number; + insertedSearchedIds?: Array<{ number: number; _id?: string; id?: string }>; }; export async function createTestTableForMSSQLWithChema( - connectionParams, - testEntitiesSeedsCount = 42, - testSearchedUserName = 'Vasia', - _schemaName = 'test_chema', + connectionParams, + testEntitiesSeedsCount = 42, + testSearchedUserName = 'Vasia', + _schemaName = 'test_chema', ) { - const testTableName = getRandomTestTableName(); - const testTableColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; - const testTableSecondColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; - const Knex = getTestKnex(connectionParams); - try { - await Knex.raw(`IF NOT EXISTS ( SELECT * + const testTableName = getRandomTestTableName(); + const testTableColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; + const testTableSecondColumnName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}`; + const Knex = getTestKnex(connectionParams); + try { + await Knex.raw(`IF NOT EXISTS ( SELECT * FROM sys.schemas WHERE name = N'test_schema' ) EXEC('CREATE SCHEMA [test_schema]');`); - } catch (e) { - console.error(`MSSQL: Error while creating schema: ${e}`); - } - - await Knex.schema.dropTableIfExists(`test_schema.${testTableName}`); - await Knex.schema.createTable(`test_schema.${testTableName}`, (table) => { - table.increments(); - table.string(testTableColumnName); - table.string(testTableSecondColumnName); - table.timestamps(); - }); - - for (let i = 0; i < testEntitiesSeedsCount; i++) { - if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { - await Knex(testTableName) - .withSchema('test_schema') - .insert({ - [testTableColumnName]: testSearchedUserName, - [testTableSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - }); - } else { - await Knex(testTableName) - .withSchema('test_schema') - .insert({ - [testTableColumnName]: faker.person.firstName(), - [testTableSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - }); - } - } - return { - testTableName: testTableName, - testTableColumnName: testTableColumnName, - testTableSecondColumnName: testTableSecondColumnName, - testEntitiesSeedsCount: testEntitiesSeedsCount, - }; + } catch (e) { + console.error(`MSSQL: Error while creating schema: ${e}`); + } + + await Knex.schema.dropTableIfExists(`test_schema.${testTableName}`); + await Knex.schema.createTable(`test_schema.${testTableName}`, (table) => { + table.increments(); + table.string(testTableColumnName); + table.string(testTableSecondColumnName); + table.timestamps(); + }); + + for (let i = 0; i < testEntitiesSeedsCount; i++) { + if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { + await Knex(testTableName) + .withSchema('test_schema') + .insert({ + [testTableColumnName]: testSearchedUserName, + [testTableSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + }); + } else { + await Knex(testTableName) + .withSchema('test_schema') + .insert({ + [testTableColumnName]: faker.person.firstName(), + [testTableSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + }); + } + } + return { + testTableName: testTableName, + testTableColumnName: testTableColumnName, + testTableSecondColumnName: testTableSecondColumnName, + testEntitiesSeedsCount: testEntitiesSeedsCount, + }; } export async function createTestOracleTable( - connectionParams, - testEntitiesSeedsCount = 42, - testSearchedUserName = 'Vasia', + connectionParams, + testEntitiesSeedsCount = 42, + testSearchedUserName = 'Vasia', ) { - const primaryKeyConstraintName = getRandomConstraintName(); - const pColumnName = 'id'; - const testTableColumnName = 'name'; - const testTableSecondColumnName = 'email'; - const { shema, username } = connectionParams; - const testTableName = getRandomTestTableName().toUpperCase(); - const Knex = getTestKnex(connectionParams); - await Knex.schema.dropTableIfExists(testTableName); - await Knex.schema.createTable(testTableName, (table) => { - table.integer(pColumnName); - table.string(testTableColumnName); - table.string(testTableSecondColumnName); - table.timestamp('created_at'); - table.date('updated_at'); - }); - await Knex.schema.alterTable(testTableName, (t) => { - t.primary([pColumnName], primaryKeyConstraintName); - }); - let counter = 0; - - if (shema) { - for (let i = 0; i < testEntitiesSeedsCount; i++) { - if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { - await Knex(testTableName) - .withSchema(username.toUpperCase()) - .insert({ - [pColumnName]: ++counter, - [testTableColumnName]: testSearchedUserName, - [testTableSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - }); - } else { - await Knex(testTableName) - .withSchema(username.toUpperCase()) - .insert({ - [pColumnName]: ++counter, - [testTableColumnName]: faker.person.firstName(), - [testTableSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - }); - } - } - } else { - for (let i = 0; i < testEntitiesSeedsCount; i++) { - if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { - await Knex(testTableName).insert({ - [pColumnName]: ++counter, - [testTableColumnName]: testSearchedUserName, - [testTableSecondColumnName]: faker.internet.email(), - created_at: new Date('2010-11-03'), - updated_at: new Date(), - }); - } else { - await Knex(testTableName).insert({ - [pColumnName]: ++counter, - [testTableColumnName]: faker.person.firstName(), - [testTableSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - }); - } - } - } - return { - testTableName: testTableName, - testTableColumnName: testTableColumnName, - testTableSecondColumnName: testTableSecondColumnName, - testEntitiesSeedsCount: testEntitiesSeedsCount, - }; + const primaryKeyConstraintName = getRandomConstraintName(); + const pColumnName = 'id'; + const testTableColumnName = 'name'; + const testTableSecondColumnName = 'email'; + const { shema, username } = connectionParams; + const testTableName = getRandomTestTableName().toUpperCase(); + const Knex = getTestKnex(connectionParams); + await Knex.schema.dropTableIfExists(testTableName); + await Knex.schema.createTable(testTableName, (table) => { + table.integer(pColumnName); + table.string(testTableColumnName); + table.string(testTableSecondColumnName); + table.timestamp('created_at'); + table.date('updated_at'); + }); + await Knex.schema.alterTable(testTableName, (t) => { + t.primary([pColumnName], primaryKeyConstraintName); + }); + let counter = 0; + + if (shema) { + for (let i = 0; i < testEntitiesSeedsCount; i++) { + if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { + await Knex(testTableName) + .withSchema(username.toUpperCase()) + .insert({ + [pColumnName]: ++counter, + [testTableColumnName]: testSearchedUserName, + [testTableSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + }); + } else { + await Knex(testTableName) + .withSchema(username.toUpperCase()) + .insert({ + [pColumnName]: ++counter, + [testTableColumnName]: faker.person.firstName(), + [testTableSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + }); + } + } + } else { + for (let i = 0; i < testEntitiesSeedsCount; i++) { + if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { + await Knex(testTableName).insert({ + [pColumnName]: ++counter, + [testTableColumnName]: testSearchedUserName, + [testTableSecondColumnName]: faker.internet.email(), + created_at: new Date('2010-11-03'), + updated_at: new Date(), + }); + } else { + await Knex(testTableName).insert({ + [pColumnName]: ++counter, + [testTableColumnName]: faker.person.firstName(), + [testTableSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + }); + } + } + } + return { + testTableName: testTableName, + testTableColumnName: testTableColumnName, + testTableSecondColumnName: testTableSecondColumnName, + testEntitiesSeedsCount: testEntitiesSeedsCount, + }; } export async function createTestOracleTableWithDifferentData( - connectionParams, - testEntitiesSeedsCount = 42, - testSearchedUserName = 'Vasia', + connectionParams, + testEntitiesSeedsCount = 42, + testSearchedUserName = 'Vasia', ) { - const _primaryKeyConstraintName = getRandomConstraintName(); - const _pColumnName = 'id'; - const _testTableColumnName = 'name'; - const _testTableSecondColumnName = 'email'; - const { shema, username } = connectionParams; - const testTableName = getRandomTestTableName().toUpperCase(); - const Knex = getTestKnex(connectionParams); - await Knex.schema.dropTableIfExists(testTableName); - - await Knex.schema.createTable(testTableName, (table) => { - table.specificType('patient_id', 'RAW(16) DEFAULT SYS_GUID()').primary(); - table.string('first_name', 100).notNullable(); - table.string('last_name', 100).notNullable(); - table.date('date_of_birth').notNullable(); - table.specificType('gender', 'CHAR(1)'); - table.string('phone_number', 40); - table.string('email', 150).unique(); - table.string('address', 300); - table.specificType('insurance_info', 'CLOB'); // Using specificType for CLOB - table.timestamp('created_at').defaultTo(Knex.raw('SYSTIMESTAMP')); - }); - - try { - await Knex.raw( - `ALTER TABLE ${testTableName} ADD CONSTRAINT chk_gender_${testTableName} CHECK ("gender" IN ('M','F','O'))`, - ); - } catch (_error) { - console.log('Warning: Could not add CHECK constraint for gender field'); - } - - let _counter = 0; - - if (shema) { - for (let i = 0; i < testEntitiesSeedsCount; i++) { - if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { - await Knex(testTableName) - .withSchema(username.toUpperCase()) - .insert({ - first_name: testSearchedUserName, - last_name: faker.person.lastName(), - date_of_birth: faker.date.past(), - gender: faker.helpers.arrayElement(['M', 'F', 'O']), - phone_number: faker.phone.number(), - email: faker.internet.email(), - address: faker.location.streetAddress(), - insurance_info: faker.lorem.sentence(), - }); - } else { - await Knex(testTableName) - .withSchema(username.toUpperCase()) - .insert({ - first_name: faker.person.firstName(), - last_name: faker.person.lastName(), - date_of_birth: faker.date.past(), - gender: faker.helpers.arrayElement(['M', 'F', 'O']), - phone_number: faker.phone.number(), - email: faker.internet.email(), - address: faker.location.streetAddress(), - insurance_info: faker.lorem.sentence(), - }); - } - } - } else { - for (let i = 0; i < testEntitiesSeedsCount; i++) { - if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { - await Knex(testTableName).insert({ - first_name: testSearchedUserName, - last_name: faker.person.lastName(), - date_of_birth: faker.date.past(), - gender: faker.helpers.arrayElement(['M', 'F', 'O']), - phone_number: faker.phone.number(), - email: faker.internet.email(), - address: faker.location.streetAddress(), - insurance_info: faker.lorem.sentence(), - }); - } else { - await Knex(testTableName).insert({ - first_name: faker.person.firstName(), - last_name: faker.person.lastName(), - date_of_birth: faker.date.past(), - gender: faker.helpers.arrayElement(['M', 'F', 'O']), - phone_number: faker.phone.number(), - email: faker.internet.email(), - address: faker.location.streetAddress(), - insurance_info: faker.lorem.sentence(), - }); - } - } - } - return { - testTableName: testTableName, - testTableColumnName: 'first_name', - testTableSecondColumnName: 'email', - testEntitiesSeedsCount: testEntitiesSeedsCount, - }; + const _primaryKeyConstraintName = getRandomConstraintName(); + const _pColumnName = 'id'; + const _testTableColumnName = 'name'; + const _testTableSecondColumnName = 'email'; + const { shema, username } = connectionParams; + const testTableName = getRandomTestTableName().toUpperCase(); + const Knex = getTestKnex(connectionParams); + await Knex.schema.dropTableIfExists(testTableName); + + await Knex.schema.createTable(testTableName, (table) => { + table.specificType('patient_id', 'RAW(16) DEFAULT SYS_GUID()').primary(); + table.string('first_name', 100).notNullable(); + table.string('last_name', 100).notNullable(); + table.date('date_of_birth').notNullable(); + table.specificType('gender', 'CHAR(1)'); + table.string('phone_number', 40); + table.string('email', 150).unique(); + table.string('address', 300); + table.specificType('insurance_info', 'CLOB'); // Using specificType for CLOB + table.timestamp('created_at').defaultTo(Knex.raw('SYSTIMESTAMP')); + }); + + try { + await Knex.raw( + `ALTER TABLE ${testTableName} ADD CONSTRAINT chk_gender_${testTableName} CHECK ("gender" IN ('M','F','O'))`, + ); + } catch (_error) { + console.log('Warning: Could not add CHECK constraint for gender field'); + } + + let _counter = 0; + + if (shema) { + for (let i = 0; i < testEntitiesSeedsCount; i++) { + if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { + await Knex(testTableName) + .withSchema(username.toUpperCase()) + .insert({ + first_name: testSearchedUserName, + last_name: faker.person.lastName(), + date_of_birth: faker.date.past(), + gender: faker.helpers.arrayElement(['M', 'F', 'O']), + phone_number: faker.phone.number(), + email: faker.internet.email(), + address: faker.location.streetAddress(), + insurance_info: faker.lorem.sentence(), + }); + } else { + await Knex(testTableName) + .withSchema(username.toUpperCase()) + .insert({ + first_name: faker.person.firstName(), + last_name: faker.person.lastName(), + date_of_birth: faker.date.past(), + gender: faker.helpers.arrayElement(['M', 'F', 'O']), + phone_number: faker.phone.number(), + email: faker.internet.email(), + address: faker.location.streetAddress(), + insurance_info: faker.lorem.sentence(), + }); + } + } + } else { + for (let i = 0; i < testEntitiesSeedsCount; i++) { + if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { + await Knex(testTableName).insert({ + first_name: testSearchedUserName, + last_name: faker.person.lastName(), + date_of_birth: faker.date.past(), + gender: faker.helpers.arrayElement(['M', 'F', 'O']), + phone_number: faker.phone.number(), + email: faker.internet.email(), + address: faker.location.streetAddress(), + insurance_info: faker.lorem.sentence(), + }); + } else { + await Knex(testTableName).insert({ + first_name: faker.person.firstName(), + last_name: faker.person.lastName(), + date_of_birth: faker.date.past(), + gender: faker.helpers.arrayElement(['M', 'F', 'O']), + phone_number: faker.phone.number(), + email: faker.internet.email(), + address: faker.location.streetAddress(), + insurance_info: faker.lorem.sentence(), + }); + } + } + } + return { + testTableName: testTableName, + testTableColumnName: 'first_name', + testTableSecondColumnName: 'email', + testEntitiesSeedsCount: testEntitiesSeedsCount, + }; } export async function createTestPostgresTableWithSchema( - connectionParams: any, - testEntitiesSeedsCount = 42, - testSearchedUserName = 'Vasia', + connectionParams: any, + testEntitiesSeedsCount = 42, + testSearchedUserName = 'Vasia', ) { - const Knex = getTestKnex(connectionParams); - const testTableName = getRandomTestTableName(); - const testSchema = 'test_schema'; - await Knex.schema.dropTableIfExists(testTableName); - - const testTableColumnName = 'name'; - const testTableSecondColumnName = 'email'; - - await Knex.schema.createSchemaIfNotExists(testSchema); - await Knex.schema.withSchema(testSchema).dropTableIfExists(testSchema); - await Knex.schema.withSchema(testSchema).createTable(testTableName, (table) => { - table.increments(); - table.string(testTableColumnName); - table.string(testTableSecondColumnName); - table.timestamps(); - }); - - for (let i = 0; i < testEntitiesSeedsCount; i++) { - if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { - await Knex(testTableName) - .withSchema(testSchema) - .insert({ - [testTableColumnName]: testSearchedUserName, - [testTableSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - }); - } else { - await Knex(testTableName) - .withSchema(testSchema) - .insert({ - [testTableColumnName]: faker.person.firstName(), - [testTableSecondColumnName]: faker.internet.email(), - created_at: new Date(), - updated_at: new Date(), - }); - } - } - return { - testTableName: testTableName, - testTableColumnName: testTableColumnName, - testTableSecondColumnName: testTableSecondColumnName, - testEntitiesSeedsCount: testEntitiesSeedsCount, - }; + const Knex = getTestKnex(connectionParams); + const testTableName = getRandomTestTableName(); + const testSchema = 'test_schema'; + await Knex.schema.dropTableIfExists(testTableName); + + const testTableColumnName = 'name'; + const testTableSecondColumnName = 'email'; + + await Knex.schema.createSchemaIfNotExists(testSchema); + await Knex.schema.withSchema(testSchema).dropTableIfExists(testSchema); + await Knex.schema.withSchema(testSchema).createTable(testTableName, (table) => { + table.increments(); + table.string(testTableColumnName); + table.string(testTableSecondColumnName); + table.timestamps(); + }); + + for (let i = 0; i < testEntitiesSeedsCount; i++) { + if (i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5) { + await Knex(testTableName) + .withSchema(testSchema) + .insert({ + [testTableColumnName]: testSearchedUserName, + [testTableSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + }); + } else { + await Knex(testTableName) + .withSchema(testSchema) + .insert({ + [testTableColumnName]: faker.person.firstName(), + [testTableSecondColumnName]: faker.internet.email(), + created_at: new Date(), + updated_at: new Date(), + }); + } + } + return { + testTableName: testTableName, + testTableColumnName: testTableColumnName, + testTableSecondColumnName: testTableSecondColumnName, + testEntitiesSeedsCount: testEntitiesSeedsCount, + }; } async function createTestDynamoDBTable( - connectionParams: any, - testEntitiesSeedsCount = 42, - testSearchedUserName = 'Vasia', + connectionParams: any, + testEntitiesSeedsCount = 42, + testSearchedUserName = 'Vasia', ) { - const dynamoDb = new DynamoDB({ - endpoint: connectionParams.host, - credentials: { - accessKeyId: connectionParams.username, - secretAccessKey: connectionParams.password, - }, - region: 'localhost', - }); - - const testTableName = getRandomTestTableName(); - const testTableColumnName = 'name'; - const testTableSecondColumnName = 'email'; - - const params = { - TableName: testTableName, - KeySchema: [ - { AttributeName: 'id', KeyType: 'HASH' }, // Primary key - ], - AttributeDefinitions: [{ AttributeName: 'id', AttributeType: 'N' }], - ProvisionedThroughput: { - ReadCapacityUnits: 5, - WriteCapacityUnits: 5, - }, - } as any; - - try { - await dynamoDb.createTable(params); - } catch (error) { - console.error(`Error creating dynamodb table: ${error.message}`); - } - const insertedSearchedIds: Array<{ number: number; id: string }> = []; - const documentClient = DynamoDBDocumentClient.from(dynamoDb); - try { - for (let i = 0; i < testEntitiesSeedsCount; i++) { - const isSearchedUser = i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5; - const item = { - id: { N: i }, - name: { S: isSearchedUser ? testSearchedUserName : faker.person.firstName() }, - email: { S: faker.internet.email() }, - age: { - N: !isSearchedUser - ? faker.number.int({ min: 16, max: 80 }) - : i === 0 - ? 14 - : i === testEntitiesSeedsCount - 21 - ? 90 - : 95, - }, - created_at: { S: new Date().toISOString() }, - updated_at: { S: new Date().toISOString() }, - list_column: { L: [{ S: 'value1' }, { S: 'value2' }] }, - set_column: { SS: ['value1', 'value2'] }, - map_column: { M: { key1: { S: 'value1' }, key2: { S: 'value2' } } }, - binary_column: { B: Buffer.from('hello') }, - binary_set_column: { BS: [Buffer.from('value1'), Buffer.from('value2')] }, - }; - - if (isSearchedUser) { - insertedSearchedIds.push({ - number: i, - id: String(item.id.N), - }); - } - - const params: PutItemCommandInput = { - TableName: testTableName, - Item: item as any, - }; - await documentClient.send(new PutItemCommand(params)); - } - } catch (error) { - console.error(`Error inserting item into dynamodb table: ${error.message}`); - throw error; - } - - return { - testTableName: testTableName, - testTableColumnName: testTableColumnName, - testTableSecondColumnName: testTableSecondColumnName, - testEntitiesSeedsCount: testEntitiesSeedsCount, - insertedSearchedIds, - }; + const dynamoDb = new DynamoDB({ + endpoint: connectionParams.host, + credentials: { + accessKeyId: connectionParams.username, + secretAccessKey: connectionParams.password, + }, + region: 'localhost', + }); + + const testTableName = getRandomTestTableName(); + const testTableColumnName = 'name'; + const testTableSecondColumnName = 'email'; + + const params = { + TableName: testTableName, + KeySchema: [ + { AttributeName: 'id', KeyType: 'HASH' }, // Primary key + ], + AttributeDefinitions: [{ AttributeName: 'id', AttributeType: 'N' }], + ProvisionedThroughput: { + ReadCapacityUnits: 5, + WriteCapacityUnits: 5, + }, + } as any; + + try { + await dynamoDb.createTable(params); + } catch (error) { + console.error(`Error creating dynamodb table: ${error.message}`); + } + const insertedSearchedIds: Array<{ number: number; id: string }> = []; + const documentClient = DynamoDBDocumentClient.from(dynamoDb); + try { + for (let i = 0; i < testEntitiesSeedsCount; i++) { + const isSearchedUser = i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5; + const item = { + id: { N: i }, + name: { S: isSearchedUser ? testSearchedUserName : faker.person.firstName() }, + email: { S: faker.internet.email() }, + age: { + N: !isSearchedUser + ? faker.number.int({ min: 16, max: 80 }) + : i === 0 + ? 14 + : i === testEntitiesSeedsCount - 21 + ? 90 + : 95, + }, + created_at: { S: new Date().toISOString() }, + updated_at: { S: new Date().toISOString() }, + list_column: { L: [{ S: 'value1' }, { S: 'value2' }] }, + set_column: { SS: ['value1', 'value2'] }, + map_column: { M: { key1: { S: 'value1' }, key2: { S: 'value2' } } }, + binary_column: { B: Buffer.from('hello') }, + binary_set_column: { BS: [Buffer.from('value1'), Buffer.from('value2')] }, + }; + + if (isSearchedUser) { + insertedSearchedIds.push({ + number: i, + id: String(item.id.N), + }); + } + + const params: PutItemCommandInput = { + TableName: testTableName, + Item: item as any, + }; + await documentClient.send(new PutItemCommand(params)); + } + } catch (error) { + console.error(`Error inserting item into dynamodb table: ${error.message}`); + throw error; + } + + return { + testTableName: testTableName, + testTableColumnName: testTableColumnName, + testTableSecondColumnName: testTableSecondColumnName, + testEntitiesSeedsCount: testEntitiesSeedsCount, + insertedSearchedIds, + }; } async function createTestCassandraTable( - connectionParams: any, - testEntitiesSeedsCount = 42, - testSearchedUserName = 'Vasia', + connectionParams: any, + testEntitiesSeedsCount = 42, + testSearchedUserName = 'Vasia', ): Promise { - const testTableName = getRandomTestTableName().toLowerCase(); - const testTableColumnName = 'name'; - const testTableSecondColumnName = 'email'; - const client = new cassandra.Client({ - contactPoints: [connectionParams.host], - localDataCenter: connectionParams.dataCenter, - authProvider: new cassandra.auth.PlainTextAuthProvider(connectionParams.username, connectionParams.password), - pooling: { - coreConnectionsPerHost: { - [cassandra.types.distance.local]: 1, - [cassandra.types.distance.remote]: 1, - }, - maxRequestsPerConnection: 32, - }, - socketOptions: { - readTimeout: 30000, - connectTimeout: 30000, - }, - }); - - try { - await client.connect(); - - try { - await client.execute( - `CREATE KEYSPACE IF NOT EXISTS ${connectionParams.database} WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 1}`, - ); - await client.execute(`USE ${connectionParams.database}`); - await client.execute( - `CREATE TABLE IF NOT EXISTS ${testTableName} (id UUID, ${testTableColumnName} TEXT, ${testTableSecondColumnName} TEXT, age INT, created_at TIMESTAMP, updated_at TIMESTAMP, PRIMARY KEY (id, age))`, - ); - } catch (error) { - console.error(`Error creating Cassandra table: ${error.message}`); - throw error; - } - const insertedSearchedIds = []; - for (let i = 0; i < testEntitiesSeedsCount; i++) { - const isSearchedUser = i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5; - - const generatedId = uuidv4(); - const query = `INSERT INTO ${testTableName} (id, ${testTableColumnName}, ${testTableSecondColumnName}, age, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)`; - const age = isSearchedUser - ? i === 0 - ? 14 - : i === testEntitiesSeedsCount - 21 - ? 90 - : 95 - : faker.number.int({ min: 16, max: 80 }); - const params = [ - generatedId, - isSearchedUser ? testSearchedUserName : faker.person.firstName(), - faker.internet.email(), - age, - new Date(), - new Date(), - ]; - try { - await client.execute(query, params, { prepare: true }); - if (isSearchedUser) { - insertedSearchedIds.push({ - number: i, - id: generatedId, - }); - } - } catch (error) { - console.error(`Error inserting into Cassandra table: ${error.message}`); - throw error; - } - } - return { - testTableName: testTableName, - testTableColumnName: testTableColumnName, - testTableSecondColumnName: testTableSecondColumnName, - testEntitiesSeedsCount: testEntitiesSeedsCount, - insertedSearchedIds, - }; - } finally { - await client.shutdown().catch((err) => console.error('Error shutting down Cassandra client:', err)); - } + const testTableName = getRandomTestTableName().toLowerCase(); + const testTableColumnName = 'name'; + const testTableSecondColumnName = 'email'; + const client = new cassandra.Client({ + contactPoints: [connectionParams.host], + localDataCenter: connectionParams.dataCenter, + authProvider: new cassandra.auth.PlainTextAuthProvider(connectionParams.username, connectionParams.password), + pooling: { + coreConnectionsPerHost: { + [cassandra.types.distance.local]: 1, + [cassandra.types.distance.remote]: 1, + }, + maxRequestsPerConnection: 32, + }, + socketOptions: { + readTimeout: 30000, + connectTimeout: 30000, + }, + }); + + try { + await client.connect(); + + try { + await client.execute( + `CREATE KEYSPACE IF NOT EXISTS ${connectionParams.database} WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 1}`, + ); + await client.execute(`USE ${connectionParams.database}`); + await client.execute( + `CREATE TABLE IF NOT EXISTS ${testTableName} (id UUID, ${testTableColumnName} TEXT, ${testTableSecondColumnName} TEXT, age INT, created_at TIMESTAMP, updated_at TIMESTAMP, PRIMARY KEY (id, age))`, + ); + } catch (error) { + console.error(`Error creating Cassandra table: ${error.message}`); + throw error; + } + const insertedSearchedIds = []; + for (let i = 0; i < testEntitiesSeedsCount; i++) { + const isSearchedUser = i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5; + + const generatedId = uuidv4(); + const query = `INSERT INTO ${testTableName} (id, ${testTableColumnName}, ${testTableSecondColumnName}, age, created_at, updated_at) VALUES (?, ?, ?, ?, ?, ?)`; + const age = isSearchedUser + ? i === 0 + ? 14 + : i === testEntitiesSeedsCount - 21 + ? 90 + : 95 + : faker.number.int({ min: 16, max: 80 }); + const params = [ + generatedId, + isSearchedUser ? testSearchedUserName : faker.person.firstName(), + faker.internet.email(), + age, + new Date(), + new Date(), + ]; + try { + await client.execute(query, params, { prepare: true }); + if (isSearchedUser) { + insertedSearchedIds.push({ + number: i, + id: generatedId, + }); + } + } catch (error) { + console.error(`Error inserting into Cassandra table: ${error.message}`); + throw error; + } + } + return { + testTableName: testTableName, + testTableColumnName: testTableColumnName, + testTableSecondColumnName: testTableSecondColumnName, + testEntitiesSeedsCount: testEntitiesSeedsCount, + insertedSearchedIds, + }; + } finally { + await client.shutdown().catch((err) => console.error('Error shutting down Cassandra client:', err)); + } } async function createTestRedisTable( - connectionParams: any, - testEntitiesSeedsCount = 42, - testSearchedUserName = 'Vasia', + connectionParams: any, + testEntitiesSeedsCount = 42, + testSearchedUserName = 'Vasia', ): Promise { - const testTableName = getRandomTestTableName().toLowerCase(); - const testTableColumnName = 'name'; - const testTableSecondColumnName = 'email'; - - const redisClient = createClient({ - socket: { - host: connectionParams.host, - port: connectionParams.port, - ca: connectionParams.cert || undefined, - cert: connectionParams.cert || undefined, - rejectUnauthorized: connectionParams.ssl !==false, - }, - password: connectionParams.password || undefined, - }); - - await redisClient.connect(); - - const existingKeys = await redisClient.keys(`${testTableName}:*`); - if (existingKeys.length > 0) { - await redisClient.del(existingKeys); - } - - const insertedSearchedIds: Array<{ number: number; id: string }> = []; - - for (let i = 0; i < testEntitiesSeedsCount; i++) { - const isSearchedUser = i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5; - const key = `user_${i}`; - const rowKey = `${testTableName}:${key}`; - - const data = { - [testTableColumnName]: isSearchedUser ? testSearchedUserName : faker.person.firstName(), - [testTableSecondColumnName]: faker.internet.email(), - age: isSearchedUser - ? i === 0 - ? 14 - : i === testEntitiesSeedsCount - 21 - ? 90 - : 95 - : faker.number.int({ min: 16, max: 80 }), - created_at: new Date().toISOString(), - updated_at: new Date().toISOString(), - }; - - await redisClient.set(rowKey, JSON.stringify(data)); - - if (isSearchedUser) { - insertedSearchedIds.push({ - number: i, - id: key, - }); - } - } - - await redisClient.quit(); - - return { - testTableName: testTableName, - testTableColumnName: testTableColumnName, - testTableSecondColumnName: testTableSecondColumnName, - testEntitiesSeedsCount: testEntitiesSeedsCount, - insertedSearchedIds, - }; + const testTableName = getRandomTestTableName().toLowerCase(); + const testTableColumnName = 'name'; + const testTableSecondColumnName = 'email'; + + const redisClient = createClient({ + socket: { + host: connectionParams.host, + port: connectionParams.port, + ca: connectionParams.cert || undefined, + cert: connectionParams.cert || undefined, + rejectUnauthorized: connectionParams.ssl !== false, + }, + password: connectionParams.password || undefined, + }); + + await redisClient.connect(); + + const existingKeys = await redisClient.keys(`${testTableName}:*`); + if (existingKeys.length > 0) { + await redisClient.del(existingKeys); + } + + const insertedSearchedIds: Array<{ number: number; id: string }> = []; + + for (let i = 0; i < testEntitiesSeedsCount; i++) { + const isSearchedUser = i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5; + const key = `user_${i}`; + const rowKey = `${testTableName}:${key}`; + + const data = { + [testTableColumnName]: isSearchedUser ? testSearchedUserName : faker.person.firstName(), + [testTableSecondColumnName]: faker.internet.email(), + age: isSearchedUser + ? i === 0 + ? 14 + : i === testEntitiesSeedsCount - 21 + ? 90 + : 95 + : faker.number.int({ min: 16, max: 80 }), + created_at: new Date().toISOString(), + updated_at: new Date().toISOString(), + }; + + await redisClient.set(rowKey, JSON.stringify(data)); + + if (isSearchedUser) { + insertedSearchedIds.push({ + number: i, + id: key, + }); + } + } + + await redisClient.quit(); + + return { + testTableName: testTableName, + testTableColumnName: testTableColumnName, + testTableSecondColumnName: testTableSecondColumnName, + testEntitiesSeedsCount: testEntitiesSeedsCount, + insertedSearchedIds, + }; } async function createTestClickHouseTable( - connectionParams: any, - testEntitiesSeedsCount = 42, - testSearchedUserName = 'Vasia', + connectionParams: any, + testEntitiesSeedsCount = 42, + testSearchedUserName = 'Vasia', ): Promise { - const testTableName = getRandomTestTableName().toLowerCase().replace(/-/g, '_'); - const testTableColumnName = 'name'; - const testTableSecondColumnName = 'email'; - - const client = createClickHouseClient({ - url: `http://${connectionParams.host}:${connectionParams.port}`, - username: connectionParams.username || 'default', - password: connectionParams.password || '', - database: connectionParams.database || 'default', - }); - - try { - await client.command({ - query: ` + const testTableName = getRandomTestTableName().toLowerCase().replace(/-/g, '_'); + const testTableColumnName = 'name'; + const testTableSecondColumnName = 'email'; + + const client = createClickHouseClient({ + url: `http://${connectionParams.host}:${connectionParams.port}`, + username: connectionParams.username || 'default', + password: connectionParams.password || '', + database: connectionParams.database || 'default', + }); + + try { + await client.command({ + query: ` CREATE TABLE IF NOT EXISTS ${testTableName} ( id UInt32, ${testTableColumnName} String, @@ -917,62 +917,62 @@ async function createTestClickHouseTable( ) ENGINE = MergeTree() ORDER BY id `, - }); - - const insertedSearchedIds: Array<{ number: number; id: string }> = []; - - const rows: Array<{ - id: number; - name: string; - email: string; - age: number; - created_at: string; - updated_at: string; - }> = []; - - for (let i = 0; i < testEntitiesSeedsCount; i++) { - const isSearchedUser = i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5; - const age = isSearchedUser - ? i === 0 - ? 14 - : i === testEntitiesSeedsCount - 21 - ? 21 - : 37 - : faker.number.int({ min: 16, max: 80 }); - - const row = { - id: i + 1, - name: isSearchedUser ? testSearchedUserName : faker.person.firstName(), - email: faker.internet.email(), - age: age, - created_at: new Date().toISOString().replace('T', ' ').substring(0, 19), - updated_at: new Date().toISOString().replace('T', ' ').substring(0, 19), - }; - - rows.push(row); - - if (isSearchedUser) { - insertedSearchedIds.push({ - number: i, - id: String(i + 1), - }); - } - } - - await client.insert({ - table: testTableName, - values: rows, - format: 'JSONEachRow', - }); - - return { - testTableName: testTableName, - testTableColumnName: testTableColumnName, - testTableSecondColumnName: testTableSecondColumnName, - testEntitiesSeedsCount: testEntitiesSeedsCount, - insertedSearchedIds, - }; - } finally { - await client.close(); - } + }); + + const insertedSearchedIds: Array<{ number: number; id: string }> = []; + + const rows: Array<{ + id: number; + name: string; + email: string; + age: number; + created_at: string; + updated_at: string; + }> = []; + + for (let i = 0; i < testEntitiesSeedsCount; i++) { + const isSearchedUser = i === 0 || i === testEntitiesSeedsCount - 21 || i === testEntitiesSeedsCount - 5; + const age = isSearchedUser + ? i === 0 + ? 14 + : i === testEntitiesSeedsCount - 21 + ? 21 + : 37 + : faker.number.int({ min: 16, max: 80 }); + + const row = { + id: i + 1, + name: isSearchedUser ? testSearchedUserName : faker.person.firstName(), + email: faker.internet.email(), + age: age, + created_at: new Date().toISOString().replace('T', ' ').substring(0, 19), + updated_at: new Date().toISOString().replace('T', ' ').substring(0, 19), + }; + + rows.push(row); + + if (isSearchedUser) { + insertedSearchedIds.push({ + number: i, + id: String(i + 1), + }); + } + } + + await client.insert({ + table: testTableName, + values: rows, + format: 'JSONEachRow', + }); + + return { + testTableName: testTableName, + testTableColumnName: testTableColumnName, + testTableSecondColumnName: testTableSecondColumnName, + testEntitiesSeedsCount: testEntitiesSeedsCount, + insertedSearchedIds, + }; + } finally { + await client.close(); + } } diff --git a/backend/test/utils/get-random-test-table-name.ts b/backend/test/utils/get-random-test-table-name.ts index b53dc29af..28c9406f1 100644 --- a/backend/test/utils/get-random-test-table-name.ts +++ b/backend/test/utils/get-random-test-table-name.ts @@ -2,11 +2,11 @@ import { faker } from '@faker-js/faker'; import { nanoid } from 'nanoid'; export function getRandomTestTableName(): string { - let testTableName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}_${nanoid(5)}_${faker.lorem.words(1)}`; - testTableName = testTableName.replace(/[-@]/g, ''); - return testTableName; + let testTableName = `${faker.lorem.words(1)}_${faker.lorem.words(1)}_${nanoid(5)}_${faker.lorem.words(1)}`; + testTableName = testTableName.replace(/[-@]/g, ''); + return testTableName; } export function getRandomConstraintName(): string { - return `${faker.lorem.words(1)}_${faker.lorem.words(1)}_${faker.lorem.words(1)}_${nanoid(5)}`; + return `${faker.lorem.words(1)}_${faker.lorem.words(1)}_${faker.lorem.words(1)}_${nanoid(5)}`; } diff --git a/backend/test/utils/get-test-data.ts b/backend/test/utils/get-test-data.ts index 848064943..ba62f6884 100644 --- a/backend/test/utils/get-test-data.ts +++ b/backend/test/utils/get-test-data.ts @@ -1,72 +1,72 @@ import { MockFactory } from '../mock.factory.js'; export function getTestData(mockFactory: MockFactory) { - const newConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); - const newEncryptedConnection = mockFactory.generateCreateEncryptedInternalConnectionDto(); - const newConnection2 = mockFactory.generateCreateConnectionDto2(); - const newEncryptedConnection2 = mockFactory.generateCreateEncryptedConnectionDto(); - const newConnectionToTestDB = mockFactory.generateCreateConnectionDtoToTEstDB(); - const updateConnection = mockFactory.generateUpdateConnectionDto(); - const newGroup1 = mockFactory.generateCreateGroupDto1(); - const newConnectionInDocker = mockFactory.generateCreateInternalConnectionDto(); - const connectionToTestMSSQL = mockFactory.generateConnectionToTestMsSQlDBInDocker(); - const connectionToTestMSSQLSchemaInDocker = mockFactory.generateConnectionToTestSchemaMsSQlDBInDocker(); - const connectionToMySQL = mockFactory.generateConnectionToTestMySQLDBInDocker(); - const connectionToOracleDB = mockFactory.generateConnectionToTestOracleDBInDocker(); - const connectionToOracleDBSchema = mockFactory.generateConnectionToSchemaOracleDBInDocker(); - const encryptedPostgresConnection = mockFactory.generateEncryptedConnectionToTestPostgresDBInDocker(); - const connectionToPostgresSchema = mockFactory.generateConnectionToTestPostgresDBWithSchemaInDocker(); - const connectionToPostgres = mockFactory.generateConnectionToTestPostgresDBInDocker(); - const internalConnection = mockFactory.generateCreateConnectionDto(); - const postgresAgentConnection = mockFactory.generateConnectionToTestDbPostgresAgent(); - const oracleAgentConnection = mockFactory.generateConnectionToTestDbOracleAgent(); - const mysqlAgentConnection = mockFactory.generateConnectionToTestDbMysqlAgent(); - const mssqlAgentConnection = mockFactory.generateConnectionToTestDbMssqlAgent(); - const connectionToIbmDb2 = mockFactory.generateConnectionToTestDbIbmDb2(); - const connectionToAgentIbmDB2 = mockFactory.generateConnectionToTestDbIbmDb2Agent(); - const mongoDbConnection = mockFactory.generateConnectionToTestMongoDBInDocker(); - const mongoDbAgentConnection = mockFactory.generateConnectionToTestMongoDBAgent(); - const dynamoDBConnection = mockFactory.generateConnectionToTestDynamoDBInDocker(); - const elasticsearchTestConnection = mockFactory.generateConnectionToTestElasticsearchInDocker(); - const cassandraTestConnection = mockFactory.generateConnectionToTestCassandraInDocker(); - const cassandraAgentTestConnection = mockFactory.generateConnectionToTestCassandraAgent(); - const redisConnection = mockFactory.generateConnectionToTestRedisInDocker(); - const redisAgentConnection = mockFactory.generateConnectionToTestRedisAgent(); - const clickhouseTestConnection = mockFactory.generateConnectionToTestClickHouseDBInDocker(); - const clickhouseAgentTestConnection = mockFactory.generateConnectionToTestClickHouseAgent(); - return { - newConnection, - newEncryptedConnection, - newConnection2, - newEncryptedConnection2, - newConnectionToTestDB, - updateConnection, - newGroup1, - newConnectionInDocker, - connectionToTestMSSQL, - connectionToTestMSSQLSchemaInDocker, - connectionToMySQL, - connectionToOracleDB, - connectionToOracleDBSchema, - encryptedPostgresConnection, - connectionToPostgresSchema, - connectionToPostgres, - internalConnection, - postgresAgentConnection, - oracleAgentConnection, - mysqlAgentConnection, - mssqlAgentConnection, - connectionToIbmDb2, - connectionToAgentIbmDB2, - mongoDbConnection, - mongoDbAgentConnection, - dynamoDBConnection, - elasticsearchTestConnection, - cassandraTestConnection, - cassandraAgentTestConnection, - redisConnection, - redisAgentConnection, - clickhouseTestConnection, - clickhouseAgentTestConnection - }; + const newConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); + const newEncryptedConnection = mockFactory.generateCreateEncryptedInternalConnectionDto(); + const newConnection2 = mockFactory.generateCreateConnectionDto2(); + const newEncryptedConnection2 = mockFactory.generateCreateEncryptedConnectionDto(); + const newConnectionToTestDB = mockFactory.generateCreateConnectionDtoToTEstDB(); + const updateConnection = mockFactory.generateUpdateConnectionDto(); + const newGroup1 = mockFactory.generateCreateGroupDto1(); + const newConnectionInDocker = mockFactory.generateCreateInternalConnectionDto(); + const connectionToTestMSSQL = mockFactory.generateConnectionToTestMsSQlDBInDocker(); + const connectionToTestMSSQLSchemaInDocker = mockFactory.generateConnectionToTestSchemaMsSQlDBInDocker(); + const connectionToMySQL = mockFactory.generateConnectionToTestMySQLDBInDocker(); + const connectionToOracleDB = mockFactory.generateConnectionToTestOracleDBInDocker(); + const connectionToOracleDBSchema = mockFactory.generateConnectionToSchemaOracleDBInDocker(); + const encryptedPostgresConnection = mockFactory.generateEncryptedConnectionToTestPostgresDBInDocker(); + const connectionToPostgresSchema = mockFactory.generateConnectionToTestPostgresDBWithSchemaInDocker(); + const connectionToPostgres = mockFactory.generateConnectionToTestPostgresDBInDocker(); + const internalConnection = mockFactory.generateCreateConnectionDto(); + const postgresAgentConnection = mockFactory.generateConnectionToTestDbPostgresAgent(); + const oracleAgentConnection = mockFactory.generateConnectionToTestDbOracleAgent(); + const mysqlAgentConnection = mockFactory.generateConnectionToTestDbMysqlAgent(); + const mssqlAgentConnection = mockFactory.generateConnectionToTestDbMssqlAgent(); + const connectionToIbmDb2 = mockFactory.generateConnectionToTestDbIbmDb2(); + const connectionToAgentIbmDB2 = mockFactory.generateConnectionToTestDbIbmDb2Agent(); + const mongoDbConnection = mockFactory.generateConnectionToTestMongoDBInDocker(); + const mongoDbAgentConnection = mockFactory.generateConnectionToTestMongoDBAgent(); + const dynamoDBConnection = mockFactory.generateConnectionToTestDynamoDBInDocker(); + const elasticsearchTestConnection = mockFactory.generateConnectionToTestElasticsearchInDocker(); + const cassandraTestConnection = mockFactory.generateConnectionToTestCassandraInDocker(); + const cassandraAgentTestConnection = mockFactory.generateConnectionToTestCassandraAgent(); + const redisConnection = mockFactory.generateConnectionToTestRedisInDocker(); + const redisAgentConnection = mockFactory.generateConnectionToTestRedisAgent(); + const clickhouseTestConnection = mockFactory.generateConnectionToTestClickHouseDBInDocker(); + const clickhouseAgentTestConnection = mockFactory.generateConnectionToTestClickHouseAgent(); + return { + newConnection, + newEncryptedConnection, + newConnection2, + newEncryptedConnection2, + newConnectionToTestDB, + updateConnection, + newGroup1, + newConnectionInDocker, + connectionToTestMSSQL, + connectionToTestMSSQLSchemaInDocker, + connectionToMySQL, + connectionToOracleDB, + connectionToOracleDBSchema, + encryptedPostgresConnection, + connectionToPostgresSchema, + connectionToPostgres, + internalConnection, + postgresAgentConnection, + oracleAgentConnection, + mysqlAgentConnection, + mssqlAgentConnection, + connectionToIbmDb2, + connectionToAgentIbmDB2, + mongoDbConnection, + mongoDbAgentConnection, + dynamoDBConnection, + elasticsearchTestConnection, + cassandraTestConnection, + cassandraAgentTestConnection, + redisConnection, + redisAgentConnection, + clickhouseTestConnection, + clickhouseAgentTestConnection, + }; } diff --git a/backend/test/utils/get-test-knex.ts b/backend/test/utils/get-test-knex.ts index 5e2a0d1ac..ce86cdf7d 100644 --- a/backend/test/utils/get-test-knex.ts +++ b/backend/test/utils/get-test-knex.ts @@ -7,48 +7,48 @@ import { ConnectionTypesEnum } from '@rocketadmin/shared-code/dist/src/shared/en const knexCache = new LRUCache(Constants.DEFAULT_CONNECTION_CACHE_OPTIONS); export function getTestKnex(connectionParams): Knex { - const cachedKnex = knexCache.get(JSON.stringify(connectionParams)) as Knex; - if (cachedKnex) { - return cachedKnex; - } - const { host, username, password, database, port, type, sid, cert, ssl } = connectionParams; - if (type === ConnectionTypesEnum.oracledb) { - const newKnex = knex({ - client: type, - connection: { - user: username, - database: database, - password: password, - connectString: `${host}:${port}/${sid ? sid : ''}`, - ssl: ssl ? { ca: cert } : { rejectUnauthorized: false }, - }, - }); - knexCache.set(JSON.stringify(connectionParams), newKnex); - return newKnex; - } + const cachedKnex = knexCache.get(JSON.stringify(connectionParams)) as Knex; + if (cachedKnex) { + return cachedKnex; + } + const { host, username, password, database, port, type, sid, cert, ssl } = connectionParams; + if (type === ConnectionTypesEnum.oracledb) { + const newKnex = knex({ + client: type, + connection: { + user: username, + database: database, + password: password, + connectString: `${host}:${port}/${sid ? sid : ''}`, + ssl: ssl ? { ca: cert } : { rejectUnauthorized: false }, + }, + }); + knexCache.set(JSON.stringify(connectionParams), newKnex); + return newKnex; + } - const newKnex = knex({ - client: type, - connection: { - host: host, - user: username, - password: password, - database: database, - port: port, - }, - }); - knexCache.set(JSON.stringify(connectionParams), newKnex); - return newKnex; + const newKnex = knex({ + client: type, + connection: { + host: host, + user: username, + password: password, + database: database, + port: port, + }, + }); + knexCache.set(JSON.stringify(connectionParams), newKnex); + return newKnex; } export async function clearAllTestKnex() { - const elements = []; - knexCache.forEach((value, key) => { - elements.push({ key, value }); - }); - for (const element of elements) { - await element.value.destroy(); - knexCache.delete(element.key); - } - knexCache.clear(); + const elements = []; + knexCache.forEach((value, key) => { + elements.push({ key, value }); + }); + for (const element of elements) { + await element.value.destroy(); + knexCache.delete(element.key); + } + knexCache.clear(); } diff --git a/backend/test/utils/send-request-to-saas-part.util.ts b/backend/test/utils/send-request-to-saas-part.util.ts index 79c1bcf4c..0d1a50206 100644 --- a/backend/test/utils/send-request-to-saas-part.util.ts +++ b/backend/test/utils/send-request-to-saas-part.util.ts @@ -1,18 +1,18 @@ type SaaSRequestMethods = 'GET' | 'POST' | 'PUT' | 'DELETE'; export async function sendRequestToSaasPart( - route: string, - method: SaaSRequestMethods, - requestBody: Record, - authCookieValue: string, + route: string, + method: SaaSRequestMethods, + requestBody: Record, + authCookieValue: string, ): Promise { - return await fetch(`http://rocketadmin-private-microservice:3001/saas/${route}`, { - method, - body: JSON.stringify(requestBody), - headers: { - Cookie: authCookieValue, - 'Content-Type': 'application/json', - Accept: 'application/json', - }, - }); + return await fetch(`http://rocketadmin-private-microservice:3001/saas/${route}`, { + method, + body: JSON.stringify(requestBody), + headers: { + Cookie: authCookieValue, + 'Content-Type': 'application/json', + Accept: 'application/json', + }, + }); } diff --git a/backend/test/utils/set-saas-env-variable.ts b/backend/test/utils/set-saas-env-variable.ts index 9ec2bf7ac..0e117e908 100644 --- a/backend/test/utils/set-saas-env-variable.ts +++ b/backend/test/utils/set-saas-env-variable.ts @@ -1,7 +1,7 @@ export function setSaasEnvVariable(value = false): void { - if(value) { - process.env.IS_SAAS = 'true'; - return; - } - delete process.env.IS_SAAS; + if (value) { + process.env.IS_SAAS = 'true'; + return; + } + delete process.env.IS_SAAS; } diff --git a/backend/test/utils/test-utilities/create-test-ibmdb2-tables.ts b/backend/test/utils/test-utilities/create-test-ibmdb2-tables.ts index f71671d0a..3ebdb93e3 100644 --- a/backend/test/utils/test-utilities/create-test-ibmdb2-tables.ts +++ b/backend/test/utils/test-utilities/create-test-ibmdb2-tables.ts @@ -2,87 +2,87 @@ import ibmdb from 'ibm_db'; import { TableCreationResult } from '../../ava-tests/complex-table-tests/complex-ibmdb2-table-e2e.test.js'; export const createTestIBMDB2TablesWithComplexPFKeys = async (connectionParams: any): Promise => { - const mainTableName = 'ORDERS_COMPLEX'; - const firstReferencedTableName = 'ORDER_ITEMS_COMPLEX'; - const referencedOnTableName = 'SHIPMENTS_COMPLEX'; - - // Create main_table - // await knex.schema.createTable(mainTableName, (table) => { - // table.integer('order_id').notNullable(); - // table.integer('customer_id').notNullable(); - // table.date('order_date'); - // table.string('status', 20); - // table.decimal('total_amount', 10, 2); - // table.primary(['order_id', 'customer_id']); - // }); - - // // Create first_referenced_table - // const firstReferencedTableQuery = knex.schema.createTable(firstReferencedTableName, (table) => { - // table.integer('order_id').notNullable(); - // table.integer('customer_id').notNullable(); - // table.increments('item_id').primary(); - // table.string('product_name', 100); - // table.integer('quantity'); - // table.decimal('price_per_unit', 10, 2); - // table - // .foreign(['order_id', 'customer_id']) - // .references(['order_id', 'customer_id']) - // .inTable(mainTableName) - // .onDelete('CASCADE'); - // }); - // await firstReferencedTableQuery; - - // // Create second_referenced_table - // await knex.schema.createTable(referencedOnTableName, (table) => { - // table.increments('shipment_id').primary(); - // table.integer('order_id'); - // table.integer('customer_id'); - // table.date('shipped_date'); - // table.string('carrier', 50); - // table.string('tracking_number', 100); - // table - // .foreign(['order_id', 'customer_id']) - // .references(['order_id', 'customer_id']) - // .inTable(mainTableName) - // .onDelete('SET NULL'); - // }); - - const connStr = `DATABASE=${connectionParams.database};HOSTNAME=${connectionParams.host};UID=${connectionParams.username};PWD=${connectionParams.password};PORT=${connectionParams.port};PROTOCOL=TCPIP`; - - const ibmDatabase = ibmdb(); - await ibmDatabase.open(connStr); - const queryCheckSchemaExists = `SELECT COUNT(*) FROM SYSCAT.SCHEMATA WHERE SCHEMANAME = '${connectionParams.schema}'`; - const schemaExists = await ibmDatabase.query(queryCheckSchemaExists); - - if (!schemaExists.length || !schemaExists[0]['1']) { - const queryCreateSchema = `CREATE SCHEMA ${connectionParams.schema}`; - try { - await ibmDatabase.query(queryCreateSchema); - } catch (error) { - console.error(`Error while creating schema: ${error}`); - console.info(`Query: ${queryCreateSchema}`); - } - } - - const queryCheckFirstTableExists = `SELECT COUNT(*) FROM SYSCAT.TABLES WHERE TABNAME = '${mainTableName}' AND TABSCHEMA = '${connectionParams.schema}'`; - const queryCheckSecondTableExists = `SELECT COUNT(*) FROM SYSCAT.TABLES WHERE TABNAME = '${firstReferencedTableName}' AND TABSCHEMA = '${connectionParams.schema}'`; - const queryCheckThirdTableExists = `SELECT COUNT(*) FROM SYSCAT.TABLES WHERE TABNAME = '${referencedOnTableName}' AND TABSCHEMA = '${connectionParams.schema}'`; - - const firstTableExists = await ibmDatabase.query(queryCheckFirstTableExists); - const secondTableExists = await ibmDatabase.query(queryCheckSecondTableExists); - const thirdTableExists = await ibmDatabase.query(queryCheckThirdTableExists); - - if (thirdTableExists.length && thirdTableExists[0]['1']) { - await ibmDatabase.query(`DROP TABLE ${connectionParams.schema}.${thirdTableExists}`); - } - if (secondTableExists.length && secondTableExists[0]['1']) { - await ibmDatabase.query(`DROP TABLE ${connectionParams.schema}.${firstReferencedTableName}`); - } - if (firstTableExists.length && firstTableExists[0]['1']) { - await ibmDatabase.query(`DROP TABLE ${connectionParams.schema}.${mainTableName}`); - } - - const queryCreateMainTable = ` + const mainTableName = 'ORDERS_COMPLEX'; + const firstReferencedTableName = 'ORDER_ITEMS_COMPLEX'; + const referencedOnTableName = 'SHIPMENTS_COMPLEX'; + + // Create main_table + // await knex.schema.createTable(mainTableName, (table) => { + // table.integer('order_id').notNullable(); + // table.integer('customer_id').notNullable(); + // table.date('order_date'); + // table.string('status', 20); + // table.decimal('total_amount', 10, 2); + // table.primary(['order_id', 'customer_id']); + // }); + + // // Create first_referenced_table + // const firstReferencedTableQuery = knex.schema.createTable(firstReferencedTableName, (table) => { + // table.integer('order_id').notNullable(); + // table.integer('customer_id').notNullable(); + // table.increments('item_id').primary(); + // table.string('product_name', 100); + // table.integer('quantity'); + // table.decimal('price_per_unit', 10, 2); + // table + // .foreign(['order_id', 'customer_id']) + // .references(['order_id', 'customer_id']) + // .inTable(mainTableName) + // .onDelete('CASCADE'); + // }); + // await firstReferencedTableQuery; + + // // Create second_referenced_table + // await knex.schema.createTable(referencedOnTableName, (table) => { + // table.increments('shipment_id').primary(); + // table.integer('order_id'); + // table.integer('customer_id'); + // table.date('shipped_date'); + // table.string('carrier', 50); + // table.string('tracking_number', 100); + // table + // .foreign(['order_id', 'customer_id']) + // .references(['order_id', 'customer_id']) + // .inTable(mainTableName) + // .onDelete('SET NULL'); + // }); + + const connStr = `DATABASE=${connectionParams.database};HOSTNAME=${connectionParams.host};UID=${connectionParams.username};PWD=${connectionParams.password};PORT=${connectionParams.port};PROTOCOL=TCPIP`; + + const ibmDatabase = ibmdb(); + await ibmDatabase.open(connStr); + const queryCheckSchemaExists = `SELECT COUNT(*) FROM SYSCAT.SCHEMATA WHERE SCHEMANAME = '${connectionParams.schema}'`; + const schemaExists = await ibmDatabase.query(queryCheckSchemaExists); + + if (!schemaExists.length || !schemaExists[0]['1']) { + const queryCreateSchema = `CREATE SCHEMA ${connectionParams.schema}`; + try { + await ibmDatabase.query(queryCreateSchema); + } catch (error) { + console.error(`Error while creating schema: ${error}`); + console.info(`Query: ${queryCreateSchema}`); + } + } + + const queryCheckFirstTableExists = `SELECT COUNT(*) FROM SYSCAT.TABLES WHERE TABNAME = '${mainTableName}' AND TABSCHEMA = '${connectionParams.schema}'`; + const queryCheckSecondTableExists = `SELECT COUNT(*) FROM SYSCAT.TABLES WHERE TABNAME = '${firstReferencedTableName}' AND TABSCHEMA = '${connectionParams.schema}'`; + const queryCheckThirdTableExists = `SELECT COUNT(*) FROM SYSCAT.TABLES WHERE TABNAME = '${referencedOnTableName}' AND TABSCHEMA = '${connectionParams.schema}'`; + + const firstTableExists = await ibmDatabase.query(queryCheckFirstTableExists); + const secondTableExists = await ibmDatabase.query(queryCheckSecondTableExists); + const thirdTableExists = await ibmDatabase.query(queryCheckThirdTableExists); + + if (thirdTableExists.length && thirdTableExists[0]['1']) { + await ibmDatabase.query(`DROP TABLE ${connectionParams.schema}.${thirdTableExists}`); + } + if (secondTableExists.length && secondTableExists[0]['1']) { + await ibmDatabase.query(`DROP TABLE ${connectionParams.schema}.${firstReferencedTableName}`); + } + if (firstTableExists.length && firstTableExists[0]['1']) { + await ibmDatabase.query(`DROP TABLE ${connectionParams.schema}.${mainTableName}`); + } + + const queryCreateMainTable = ` CREATE TABLE ${connectionParams.schema}.${mainTableName} ( order_id INT NOT NULL, customer_id INT NOT NULL, @@ -93,7 +93,7 @@ export const createTestIBMDB2TablesWithComplexPFKeys = async (connectionParams: ) `; - const queryCreateFirstReferencedTable = ` + const queryCreateFirstReferencedTable = ` CREATE TABLE ${connectionParams.schema}.${firstReferencedTableName} ( order_id INT NOT NULL, customer_id INT NOT NULL, @@ -105,7 +105,7 @@ export const createTestIBMDB2TablesWithComplexPFKeys = async (connectionParams: ) `; - const queryCreateSecondReferencedTable = ` + const queryCreateSecondReferencedTable = ` CREATE TABLE ${connectionParams.schema}.${referencedOnTableName} ( shipment_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, order_id INT, @@ -117,22 +117,22 @@ export const createTestIBMDB2TablesWithComplexPFKeys = async (connectionParams: ) `; - try { - await ibmDatabase.query(queryCreateMainTable); - await ibmDatabase.query(queryCreateFirstReferencedTable); - await ibmDatabase.query(queryCreateSecondReferencedTable); - } catch (error) { - console.error(`Error while creating tables: ${error}`); - console.info(`Queries: + try { + await ibmDatabase.query(queryCreateMainTable); + await ibmDatabase.query(queryCreateFirstReferencedTable); + await ibmDatabase.query(queryCreateSecondReferencedTable); + } catch (error) { + console.error(`Error while creating tables: ${error}`); + console.info(`Queries: ${queryCreateMainTable} ${queryCreateFirstReferencedTable} ${queryCreateSecondReferencedTable} `); - } + } - // populate tables with test data + // populate tables with test data - const insertMainTableData = ` + const insertMainTableData = ` INSERT INTO ${connectionParams.schema}.${mainTableName} (order_id, customer_id, order_date, status, total_amount) VALUES (1, 101, '2023-01-15', 'Shipped', 250.75), (2, 102, '2023-01-16', 'Processing', 150.50), @@ -178,7 +178,7 @@ export const createTestIBMDB2TablesWithComplexPFKeys = async (connectionParams: (42, 142, '2023-02-25', 'Processing', 435.90) `; - const insertFirstReferencedTableData = ` + const insertFirstReferencedTableData = ` INSERT INTO ${connectionParams.schema}.${firstReferencedTableName} (order_id, customer_id, product_name, quantity, price_per_unit) VALUES (1, 101, 'Product A', 2, 50.00), (2, 102, 'Product B', 3, 30.25), @@ -224,7 +224,7 @@ export const createTestIBMDB2TablesWithComplexPFKeys = async (connectionParams: (42, 142, 'Product AP', 2, 217.95) `; - const insertSecondReferencedTableData = ` + const insertSecondReferencedTableData = ` INSERT INTO ${connectionParams.schema}.${referencedOnTableName} (order_id, customer_id, shipped_date, carrier, tracking_number) VALUES (1, 101, '2023-01-18', 'Carrier X', 'TRACK12345'), (3, 103, '2023-01-20', 'Carrier Y', 'TRACK67890'), @@ -270,84 +270,84 @@ export const createTestIBMDB2TablesWithComplexPFKeys = async (connectionParams: (41, 141, '2023-02-28', 'Carrier Y', 'TRACK11321') `; - try { - await ibmDatabase.query(insertMainTableData); - await ibmDatabase.query(insertFirstReferencedTableData); - await ibmDatabase.query(insertSecondReferencedTableData); - } catch (error) { - console.error(`Error while inserting data: ${error}`); - console.info(`Insert Queries: + try { + await ibmDatabase.query(insertMainTableData); + await ibmDatabase.query(insertFirstReferencedTableData); + await ibmDatabase.query(insertSecondReferencedTableData); + } catch (error) { + console.error(`Error while inserting data: ${error}`); + console.info(`Insert Queries: ${insertMainTableData} ${insertFirstReferencedTableData} ${insertSecondReferencedTableData} `); - } - - await ibmDatabase.close(); - - return { - first_referenced_table: { - table_name: firstReferencedTableName, - column_names: ['order_id', 'customer_id', 'item_id', 'product_name', 'quantity', 'price_per_unit'], - primary_key_column_names: ['item_id'], - }, - main_table: { - table_name: mainTableName, - column_names: ['order_id', 'customer_id', 'order_date', 'status', 'total_amount'], - foreign_key_column_names: [], - binary_column_names: [], - primary_key_column_names: ['order_id', 'customer_id'], - }, - second_referenced_table: { - table_name: referencedOnTableName, - column_names: ['shipment_id', 'order_id', 'customer_id', 'shipped_date', 'carrier', 'tracking_number'], - primary_key_column_names: ['shipment_id'], - foreign_key_column_names: ['order_id', 'customer_id'], - }, - }; + } + + await ibmDatabase.close(); + + return { + first_referenced_table: { + table_name: firstReferencedTableName, + column_names: ['order_id', 'customer_id', 'item_id', 'product_name', 'quantity', 'price_per_unit'], + primary_key_column_names: ['item_id'], + }, + main_table: { + table_name: mainTableName, + column_names: ['order_id', 'customer_id', 'order_date', 'status', 'total_amount'], + foreign_key_column_names: [], + binary_column_names: [], + primary_key_column_names: ['order_id', 'customer_id'], + }, + second_referenced_table: { + table_name: referencedOnTableName, + column_names: ['shipment_id', 'order_id', 'customer_id', 'shipped_date', 'carrier', 'tracking_number'], + primary_key_column_names: ['shipment_id'], + foreign_key_column_names: ['order_id', 'customer_id'], + }, + }; }; export const createTestIBMDB2TablesWithSimplePFKeys = async (connectionParams: any): Promise => { - const mainTableName = 'ORDERS_SIMPLE'; - const firstReferencedTableName = 'ORDER_ITEMS_SIMPLE'; - const referencedOnTableName = 'SHIPMENTS_SIMPLE'; - - const connStr = `DATABASE=${connectionParams.database};HOSTNAME=${connectionParams.host};UID=${connectionParams.username};PWD=${connectionParams.password};PORT=${connectionParams.port};PROTOCOL=TCPIP`; - - const ibmDatabase = ibmdb(); - await ibmDatabase.open(connStr); - const queryCheckSchemaExists = `SELECT COUNT(*) FROM SYSCAT.SCHEMATA WHERE SCHEMANAME = '${connectionParams.schema}'`; - const schemaExists = await ibmDatabase.query(queryCheckSchemaExists); - - if (!schemaExists.length || !schemaExists[0]['1']) { - const queryCreateSchema = `CREATE SCHEMA ${connectionParams.schema}`; - try { - await ibmDatabase.query(queryCreateSchema); - } catch (error) { - console.error(`Error while creating schema: ${error}`); - console.info(`Query: ${queryCreateSchema}`); - } - } - - const queryCheckFirstTableExists = `SELECT COUNT(*) FROM SYSCAT.TABLES WHERE TABNAME = '${mainTableName}' AND TABSCHEMA = '${connectionParams.schema}'`; - const queryCheckSecondTableExists = `SELECT COUNT(*) FROM SYSCAT.TABLES WHERE TABNAME = '${firstReferencedTableName}' AND TABSCHEMA = '${connectionParams.schema}'`; - const queryCheckThirdTableExists = `SELECT COUNT(*) FROM SYSCAT.TABLES WHERE TABNAME = '${referencedOnTableName}' AND TABSCHEMA = '${connectionParams.schema}'`; - - const firstTableExists = await ibmDatabase.query(queryCheckFirstTableExists); - const secondTableExists = await ibmDatabase.query(queryCheckSecondTableExists); - const thirdTableExists = await ibmDatabase.query(queryCheckThirdTableExists); - - if (thirdTableExists.length && thirdTableExists[0]['1']) { - await ibmDatabase.query(`DROP TABLE ${connectionParams.schema}.${referencedOnTableName}`); - } - if (secondTableExists.length && secondTableExists[0]['1']) { - await ibmDatabase.query(`DROP TABLE ${connectionParams.schema}.${firstReferencedTableName}`); - } - if (firstTableExists.length && firstTableExists[0]['1']) { - await ibmDatabase.query(`DROP TABLE ${connectionParams.schema}.${mainTableName}`); - } - - const queryCreateMainTable = ` + const mainTableName = 'ORDERS_SIMPLE'; + const firstReferencedTableName = 'ORDER_ITEMS_SIMPLE'; + const referencedOnTableName = 'SHIPMENTS_SIMPLE'; + + const connStr = `DATABASE=${connectionParams.database};HOSTNAME=${connectionParams.host};UID=${connectionParams.username};PWD=${connectionParams.password};PORT=${connectionParams.port};PROTOCOL=TCPIP`; + + const ibmDatabase = ibmdb(); + await ibmDatabase.open(connStr); + const queryCheckSchemaExists = `SELECT COUNT(*) FROM SYSCAT.SCHEMATA WHERE SCHEMANAME = '${connectionParams.schema}'`; + const schemaExists = await ibmDatabase.query(queryCheckSchemaExists); + + if (!schemaExists.length || !schemaExists[0]['1']) { + const queryCreateSchema = `CREATE SCHEMA ${connectionParams.schema}`; + try { + await ibmDatabase.query(queryCreateSchema); + } catch (error) { + console.error(`Error while creating schema: ${error}`); + console.info(`Query: ${queryCreateSchema}`); + } + } + + const queryCheckFirstTableExists = `SELECT COUNT(*) FROM SYSCAT.TABLES WHERE TABNAME = '${mainTableName}' AND TABSCHEMA = '${connectionParams.schema}'`; + const queryCheckSecondTableExists = `SELECT COUNT(*) FROM SYSCAT.TABLES WHERE TABNAME = '${firstReferencedTableName}' AND TABSCHEMA = '${connectionParams.schema}'`; + const queryCheckThirdTableExists = `SELECT COUNT(*) FROM SYSCAT.TABLES WHERE TABNAME = '${referencedOnTableName}' AND TABSCHEMA = '${connectionParams.schema}'`; + + const firstTableExists = await ibmDatabase.query(queryCheckFirstTableExists); + const secondTableExists = await ibmDatabase.query(queryCheckSecondTableExists); + const thirdTableExists = await ibmDatabase.query(queryCheckThirdTableExists); + + if (thirdTableExists.length && thirdTableExists[0]['1']) { + await ibmDatabase.query(`DROP TABLE ${connectionParams.schema}.${referencedOnTableName}`); + } + if (secondTableExists.length && secondTableExists[0]['1']) { + await ibmDatabase.query(`DROP TABLE ${connectionParams.schema}.${firstReferencedTableName}`); + } + if (firstTableExists.length && firstTableExists[0]['1']) { + await ibmDatabase.query(`DROP TABLE ${connectionParams.schema}.${mainTableName}`); + } + + const queryCreateMainTable = ` CREATE TABLE ${connectionParams.schema}.${mainTableName} ( order_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, customer_id INT NOT NULL, @@ -357,7 +357,7 @@ export const createTestIBMDB2TablesWithSimplePFKeys = async (connectionParams: a ) `; - const queryCreateFirstReferencedTable = ` + const queryCreateFirstReferencedTable = ` CREATE TABLE ${connectionParams.schema}.${firstReferencedTableName} ( item_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, order_id INT NOT NULL, @@ -368,7 +368,7 @@ export const createTestIBMDB2TablesWithSimplePFKeys = async (connectionParams: a ) `; - const queryCreateSecondReferencedTable = ` + const queryCreateSecondReferencedTable = ` CREATE TABLE ${connectionParams.schema}.${referencedOnTableName} ( shipment_id INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY, order_id INT, @@ -379,22 +379,22 @@ export const createTestIBMDB2TablesWithSimplePFKeys = async (connectionParams: a ) `; - try { - await ibmDatabase.query(queryCreateMainTable); - await ibmDatabase.query(queryCreateFirstReferencedTable); - await ibmDatabase.query(queryCreateSecondReferencedTable); - } catch (error) { - console.error(`Error while creating tables: ${error}`); - console.info(`Queries: + try { + await ibmDatabase.query(queryCreateMainTable); + await ibmDatabase.query(queryCreateFirstReferencedTable); + await ibmDatabase.query(queryCreateSecondReferencedTable); + } catch (error) { + console.error(`Error while creating tables: ${error}`); + console.info(`Queries: ${queryCreateMainTable} ${queryCreateFirstReferencedTable} ${queryCreateSecondReferencedTable} `); - } + } - // populate tables with test data + // populate tables with test data - const insertMainTableData = ` + const insertMainTableData = ` INSERT INTO ${connectionParams.schema}.${mainTableName} (customer_id, order_date, status, total_amount) VALUES (101, '2023-01-15', 'Shipped', 250.75), (102, '2023-01-16', 'Processing', 150.50), @@ -440,7 +440,7 @@ export const createTestIBMDB2TablesWithSimplePFKeys = async (connectionParams: a (142, '2023-02-25', 'Processing', 435.90) `; - const insertFirstReferencedTableData = ` + const insertFirstReferencedTableData = ` INSERT INTO ${connectionParams.schema}.${firstReferencedTableName} (order_id, product_name, quantity, price_per_unit) VALUES (1, 'Product A', 2, 50.00), (2, 'Product B', 3, 30.25), @@ -486,7 +486,7 @@ export const createTestIBMDB2TablesWithSimplePFKeys = async (connectionParams: a (42, 'Product AP', 2, 217.95) `; - const insertSecondReferencedTableData = ` + const insertSecondReferencedTableData = ` INSERT INTO ${connectionParams.schema}.${referencedOnTableName} (order_id, shipped_date, carrier, tracking_number) VALUES (1, '2023-01-18', 'Carrier X', 'TRACK12345'), (3, '2023-01-20', 'Carrier Y', 'TRACK67890'), @@ -532,39 +532,39 @@ export const createTestIBMDB2TablesWithSimplePFKeys = async (connectionParams: a (41, '2023-02-28', 'Carrier Y', 'TRACK11321') `; - try { - await ibmDatabase.query(insertMainTableData); - await ibmDatabase.query(insertFirstReferencedTableData); - await ibmDatabase.query(insertSecondReferencedTableData); - } catch (error) { - console.error(`Error while inserting data: ${error}`); - console.info(`Insert Queries: + try { + await ibmDatabase.query(insertMainTableData); + await ibmDatabase.query(insertFirstReferencedTableData); + await ibmDatabase.query(insertSecondReferencedTableData); + } catch (error) { + console.error(`Error while inserting data: ${error}`); + console.info(`Insert Queries: ${insertMainTableData} ${insertFirstReferencedTableData} ${insertSecondReferencedTableData} `); - } - - await ibmDatabase.close(); - - return { - main_table: { - table_name: mainTableName, - column_names: ['order_id', 'customer_id', 'order_date', 'status', 'total_amount'], - foreign_key_column_names: [], - binary_column_names: [], - primary_key_column_names: ['order_id'], - }, - first_referenced_table: { - table_name: firstReferencedTableName, - column_names: ['item_id', 'order_id', 'product_name', 'quantity', 'price_per_unit'], - primary_key_column_names: ['item_id'], - }, - second_referenced_table: { - table_name: referencedOnTableName, - column_names: ['shipment_id', 'order_id', 'shipped_date', 'carrier', 'tracking_number'], - primary_key_column_names: ['shipment_id'], - foreign_key_column_names: ['order_id'], - }, - }; + } + + await ibmDatabase.close(); + + return { + main_table: { + table_name: mainTableName, + column_names: ['order_id', 'customer_id', 'order_date', 'status', 'total_amount'], + foreign_key_column_names: [], + binary_column_names: [], + primary_key_column_names: ['order_id'], + }, + first_referenced_table: { + table_name: firstReferencedTableName, + column_names: ['item_id', 'order_id', 'product_name', 'quantity', 'price_per_unit'], + primary_key_column_names: ['item_id'], + }, + second_referenced_table: { + table_name: referencedOnTableName, + column_names: ['shipment_id', 'order_id', 'shipped_date', 'carrier', 'tracking_number'], + primary_key_column_names: ['shipment_id'], + foreign_key_column_names: ['order_id'], + }, + }; }; diff --git a/backend/test/utils/test-utilities/create-test-mysql-tables.ts b/backend/test/utils/test-utilities/create-test-mysql-tables.ts index 26f28fadc..d8da54072 100644 --- a/backend/test/utils/test-utilities/create-test-mysql-tables.ts +++ b/backend/test/utils/test-utilities/create-test-mysql-tables.ts @@ -2,271 +2,271 @@ import { getTestKnex } from '../get-test-knex.js'; import { faker } from '@faker-js/faker'; export const createTestMySQLTablesWithComplexPFKeys = async (connectionParams: any) => { - const connectionParamsCopy = { - ...connectionParams, - }; - if (connectionParams.type === 'mysql') { - connectionParamsCopy.type = 'mysql2'; - } - - const knex = getTestKnex(connectionParamsCopy); - - const mainTableName = 'Orders_Complex'; - const firstReferencedTableName = 'OrderItems_Complex'; - const referencedOnTableName = 'Shipments_Complex'; - - await knex.schema.dropTableIfExists(referencedOnTableName); - await knex.schema.dropTableIfExists(firstReferencedTableName); - await knex.schema.dropTableIfExists(mainTableName); - - await knex.schema.createTable(mainTableName, (table) => { - table.integer('order_id').notNullable(); - table.integer('customer_id').notNullable(); - table.date('order_date'); - table.string('status', 20); - table.decimal('total_amount', 10, 2); - table.primary(['order_id', 'customer_id']); - }); - - const firstReferencedTableQuery = knex.schema.createTable(firstReferencedTableName, (table) => { - table.integer('order_id').notNullable(); - table.integer('customer_id').notNullable(); - table.increments('item_id').primary(); - table.string('product_name', 100); - table.integer('quantity'); - table.decimal('price_per_unit', 10, 2); - table - .foreign(['order_id', 'customer_id']) - .references(['order_id', 'customer_id']) - .inTable(mainTableName) - .onDelete('CASCADE'); - }); - console.log('SQL Query for first_referenced_table:', firstReferencedTableQuery.toString()); - await firstReferencedTableQuery; - - await knex.schema.createTable(referencedOnTableName, (table) => { - table.increments('shipment_id').primary(); - table.integer('order_id'); - table.integer('customer_id'); - table.date('shipped_date'); - table.string('carrier', 50); - table.string('tracking_number', 100); - table - .foreign(['order_id', 'customer_id']) - .references(['order_id', 'customer_id']) - .inTable(mainTableName) - .onDelete('SET NULL'); - }); - - // seeding data in test tables - - const testEntitiesCount = 42; - - const mainTableInserts = []; - const firstReferencedTableInserts = []; - const secondReferencedTableInserts = []; - - for (let i = 0; i < testEntitiesCount; i++) { - const orderId = i + 1; - const customerId = 100 + i; - mainTableInserts.push({ - order_id: orderId, - customer_id: customerId, - order_date: faker.date.past({ years: 1 }), - status: faker.helpers.arrayElement(['Pending', 'Shipped', 'Delivered', 'Cancelled']), - total_amount: parseFloat(faker.commerce.price({ min: 20, max: 500, dec: 2 })), - }); - - const itemsCount = faker.number.int({ min: 1, max: 5 }); - for (let j = 0; j < itemsCount; j++) { - firstReferencedTableInserts.push({ - order_id: orderId, - customer_id: customerId, - product_name: faker.commerce.productName(), - quantity: faker.number.int({ min: 1, max: 10 }), - price_per_unit: parseFloat(faker.commerce.price({ min: 5, max: 100, dec: 2 })), - }); - } - - if (faker.datatype.boolean()) { - secondReferencedTableInserts.push({ - order_id: orderId, - customer_id: customerId, - shipped_date: faker.date.recent({ days: 30 }), - carrier: faker.company.name(), - tracking_number: faker.string.uuid(), - }); - } - } - - await knex(mainTableName).insert(mainTableInserts); - await knex(firstReferencedTableName).insert(firstReferencedTableInserts); - await knex(referencedOnTableName).insert(secondReferencedTableInserts); - - const mainTableColumnData = await knex(mainTableName).columnInfo(); - const firstReferencedTableColumnData = await knex(firstReferencedTableName).columnInfo(); - const secondReferencedTableColumnData = await knex(referencedOnTableName).columnInfo(); - - return { - main_table: { - table_name: mainTableName, - column_names: Object.keys(mainTableColumnData), - foreign_key_column_names: [], - binary_column_names: [], - primary_key_column_names: ['order_id', 'customer_id'], - }, - first_referenced_table: { - table_name: firstReferencedTableName, - column_names: Object.keys(firstReferencedTableColumnData), - primary_key_column_names: ['item_id'], - }, - second_referenced_table: { - table_name: referencedOnTableName, - column_names: Object.keys(secondReferencedTableColumnData), - primary_key_column_names: ['shipment_id'], - foreign_key_column_names: [], - }, - }; + const connectionParamsCopy = { + ...connectionParams, + }; + if (connectionParams.type === 'mysql') { + connectionParamsCopy.type = 'mysql2'; + } + + const knex = getTestKnex(connectionParamsCopy); + + const mainTableName = 'Orders_Complex'; + const firstReferencedTableName = 'OrderItems_Complex'; + const referencedOnTableName = 'Shipments_Complex'; + + await knex.schema.dropTableIfExists(referencedOnTableName); + await knex.schema.dropTableIfExists(firstReferencedTableName); + await knex.schema.dropTableIfExists(mainTableName); + + await knex.schema.createTable(mainTableName, (table) => { + table.integer('order_id').notNullable(); + table.integer('customer_id').notNullable(); + table.date('order_date'); + table.string('status', 20); + table.decimal('total_amount', 10, 2); + table.primary(['order_id', 'customer_id']); + }); + + const firstReferencedTableQuery = knex.schema.createTable(firstReferencedTableName, (table) => { + table.integer('order_id').notNullable(); + table.integer('customer_id').notNullable(); + table.increments('item_id').primary(); + table.string('product_name', 100); + table.integer('quantity'); + table.decimal('price_per_unit', 10, 2); + table + .foreign(['order_id', 'customer_id']) + .references(['order_id', 'customer_id']) + .inTable(mainTableName) + .onDelete('CASCADE'); + }); + console.log('SQL Query for first_referenced_table:', firstReferencedTableQuery.toString()); + await firstReferencedTableQuery; + + await knex.schema.createTable(referencedOnTableName, (table) => { + table.increments('shipment_id').primary(); + table.integer('order_id'); + table.integer('customer_id'); + table.date('shipped_date'); + table.string('carrier', 50); + table.string('tracking_number', 100); + table + .foreign(['order_id', 'customer_id']) + .references(['order_id', 'customer_id']) + .inTable(mainTableName) + .onDelete('SET NULL'); + }); + + // seeding data in test tables + + const testEntitiesCount = 42; + + const mainTableInserts = []; + const firstReferencedTableInserts = []; + const secondReferencedTableInserts = []; + + for (let i = 0; i < testEntitiesCount; i++) { + const orderId = i + 1; + const customerId = 100 + i; + mainTableInserts.push({ + order_id: orderId, + customer_id: customerId, + order_date: faker.date.past({ years: 1 }), + status: faker.helpers.arrayElement(['Pending', 'Shipped', 'Delivered', 'Cancelled']), + total_amount: parseFloat(faker.commerce.price({ min: 20, max: 500, dec: 2 })), + }); + + const itemsCount = faker.number.int({ min: 1, max: 5 }); + for (let j = 0; j < itemsCount; j++) { + firstReferencedTableInserts.push({ + order_id: orderId, + customer_id: customerId, + product_name: faker.commerce.productName(), + quantity: faker.number.int({ min: 1, max: 10 }), + price_per_unit: parseFloat(faker.commerce.price({ min: 5, max: 100, dec: 2 })), + }); + } + + if (faker.datatype.boolean()) { + secondReferencedTableInserts.push({ + order_id: orderId, + customer_id: customerId, + shipped_date: faker.date.recent({ days: 30 }), + carrier: faker.company.name(), + tracking_number: faker.string.uuid(), + }); + } + } + + await knex(mainTableName).insert(mainTableInserts); + await knex(firstReferencedTableName).insert(firstReferencedTableInserts); + await knex(referencedOnTableName).insert(secondReferencedTableInserts); + + const mainTableColumnData = await knex(mainTableName).columnInfo(); + const firstReferencedTableColumnData = await knex(firstReferencedTableName).columnInfo(); + const secondReferencedTableColumnData = await knex(referencedOnTableName).columnInfo(); + + return { + main_table: { + table_name: mainTableName, + column_names: Object.keys(mainTableColumnData), + foreign_key_column_names: [], + binary_column_names: [], + primary_key_column_names: ['order_id', 'customer_id'], + }, + first_referenced_table: { + table_name: firstReferencedTableName, + column_names: Object.keys(firstReferencedTableColumnData), + primary_key_column_names: ['item_id'], + }, + second_referenced_table: { + table_name: referencedOnTableName, + column_names: Object.keys(secondReferencedTableColumnData), + primary_key_column_names: ['shipment_id'], + foreign_key_column_names: [], + }, + }; }; export const createTestMySQLTablesWithSimplePFKeys = async (connectionParams: any) => { - const connectionParamsCopy = { - ...connectionParams, - }; - if (connectionParams.type === 'mysql') { - connectionParamsCopy.type = 'mysql2'; - } - - const knex = getTestKnex(connectionParamsCopy); - - // -- Table 1: Customers (simple primary key) - // CREATE TABLE customers ( - // customer_id SERIAL PRIMARY KEY, - // name VARCHAR(100), - // email VARCHAR(100), - // created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP - // ); - - // -- Table 2: Orders (foreign key to Customers) - // CREATE TABLE orders ( - // order_id SERIAL PRIMARY KEY, - // customer_id INT, - // order_date DATE, - // status VARCHAR(20), - // total_amount DECIMAL(10, 2), - // FOREIGN KEY (customer_id) - // REFERENCES customers(customer_id) - // ON DELETE CASCADE - // ); - - // -- Table 3: Shipments (foreign key to Orders) - // CREATE TABLE shipments ( - // shipment_id SERIAL PRIMARY KEY, - // order_id INT, - // shipped_date DATE, - // carrier VARCHAR(50), - // tracking_number VARCHAR(100), - // FOREIGN KEY (order_id) - // REFERENCES orders(order_id) - // ON DELETE SET NULL - // ); - - const mainTableName = 'Customers_Simple'; - const firstReferencedTableName = 'Orders_Simple'; - const secondReferencedTableName = 'Shipments_Simple'; - - await knex.schema.dropTableIfExists(secondReferencedTableName); - await knex.schema.dropTableIfExists(firstReferencedTableName); - await knex.schema.dropTableIfExists(mainTableName); - - await knex.schema.createTable(mainTableName, (table) => { - table.increments('customer_id').primary(); - table.string('name', 100); - table.string('email', 100); - table.timestamp('created_at').defaultTo(knex.fn.now()); - }); - - await knex.schema.createTable(firstReferencedTableName, (table) => { - table.increments('order_id').primary(); - table.integer('customer_id').unsigned().notNullable(); - table.date('order_date'); - table.string('status', 20); - table.decimal('total_amount', 10, 2); - table.foreign('customer_id').references('customer_id').inTable(mainTableName).onDelete('CASCADE'); - }); - - await knex.schema.createTable(secondReferencedTableName, (table) => { - table.increments('shipment_id').primary(); - table.integer('order_id').unsigned(); - table.date('shipped_date'); - table.string('carrier', 50); - table.string('tracking_number', 100); - table.foreign('order_id').references('order_id').inTable(firstReferencedTableName).onDelete('SET NULL'); - }); - - // seeding data in test tables - - const testEntitiesCount = 42; - - const secondReferencedTableInserts = []; - - const insertedCustomerIds = []; - for (let i = 0; i < testEntitiesCount; i++) { - const [customerId] = await knex(mainTableName).insert({ - name: faker.person.fullName(), - email: faker.internet.email(), - }); - insertedCustomerIds.push(customerId); - } - - const insertedOrderIds = []; - for (let i = 0; i < testEntitiesCount; i++) { - const customerId = insertedCustomerIds[i]; - const [orderId] = await knex(firstReferencedTableName).insert({ - customer_id: customerId, - order_date: faker.date.past({ years: 1 }), - status: faker.helpers.arrayElement(['Pending', 'Shipped', 'Delivered', 'Cancelled']), - total_amount: parseFloat(faker.commerce.price({ min: 20, max: 500, dec: 2 })), - }); - insertedOrderIds.push(orderId); - - if (faker.datatype.boolean()) { - secondReferencedTableInserts.push({ - order_id: orderId, - shipped_date: faker.date.recent({ days: 30 }), - carrier: faker.company.name(), - tracking_number: faker.string.uuid(), - }); - } - } - - if (secondReferencedTableInserts.length > 0) { - await knex(secondReferencedTableName).insert(secondReferencedTableInserts); - } - - const mainTableColumnData = await knex(mainTableName).columnInfo(); - const firstReferencedTableColumnData = await knex(firstReferencedTableName).columnInfo(); - const secondReferencedTableColumnData = await knex(secondReferencedTableName).columnInfo(); - - return { - main_table: { - table_name: mainTableName, - column_names: Object.keys(mainTableColumnData), - foreign_key_column_names: [], - binary_column_names: [], - primary_key_column_names: ['customer_id'], - }, - first_referenced_table: { - table_name: firstReferencedTableName, - column_names: Object.keys(firstReferencedTableColumnData), - primary_key_column_names: ['order_id'], - foreign_key_column_names: ['customer_id'], - }, - second_referenced_table: { - table_name: secondReferencedTableName, - column_names: Object.keys(secondReferencedTableColumnData), - primary_key_column_names: ['shipment_id'], - foreign_key_column_names: ['order_id'], - }, - }; + const connectionParamsCopy = { + ...connectionParams, + }; + if (connectionParams.type === 'mysql') { + connectionParamsCopy.type = 'mysql2'; + } + + const knex = getTestKnex(connectionParamsCopy); + + // -- Table 1: Customers (simple primary key) + // CREATE TABLE customers ( + // customer_id SERIAL PRIMARY KEY, + // name VARCHAR(100), + // email VARCHAR(100), + // created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + // ); + + // -- Table 2: Orders (foreign key to Customers) + // CREATE TABLE orders ( + // order_id SERIAL PRIMARY KEY, + // customer_id INT, + // order_date DATE, + // status VARCHAR(20), + // total_amount DECIMAL(10, 2), + // FOREIGN KEY (customer_id) + // REFERENCES customers(customer_id) + // ON DELETE CASCADE + // ); + + // -- Table 3: Shipments (foreign key to Orders) + // CREATE TABLE shipments ( + // shipment_id SERIAL PRIMARY KEY, + // order_id INT, + // shipped_date DATE, + // carrier VARCHAR(50), + // tracking_number VARCHAR(100), + // FOREIGN KEY (order_id) + // REFERENCES orders(order_id) + // ON DELETE SET NULL + // ); + + const mainTableName = 'Customers_Simple'; + const firstReferencedTableName = 'Orders_Simple'; + const secondReferencedTableName = 'Shipments_Simple'; + + await knex.schema.dropTableIfExists(secondReferencedTableName); + await knex.schema.dropTableIfExists(firstReferencedTableName); + await knex.schema.dropTableIfExists(mainTableName); + + await knex.schema.createTable(mainTableName, (table) => { + table.increments('customer_id').primary(); + table.string('name', 100); + table.string('email', 100); + table.timestamp('created_at').defaultTo(knex.fn.now()); + }); + + await knex.schema.createTable(firstReferencedTableName, (table) => { + table.increments('order_id').primary(); + table.integer('customer_id').unsigned().notNullable(); + table.date('order_date'); + table.string('status', 20); + table.decimal('total_amount', 10, 2); + table.foreign('customer_id').references('customer_id').inTable(mainTableName).onDelete('CASCADE'); + }); + + await knex.schema.createTable(secondReferencedTableName, (table) => { + table.increments('shipment_id').primary(); + table.integer('order_id').unsigned(); + table.date('shipped_date'); + table.string('carrier', 50); + table.string('tracking_number', 100); + table.foreign('order_id').references('order_id').inTable(firstReferencedTableName).onDelete('SET NULL'); + }); + + // seeding data in test tables + + const testEntitiesCount = 42; + + const secondReferencedTableInserts = []; + + const insertedCustomerIds = []; + for (let i = 0; i < testEntitiesCount; i++) { + const [customerId] = await knex(mainTableName).insert({ + name: faker.person.fullName(), + email: faker.internet.email(), + }); + insertedCustomerIds.push(customerId); + } + + const insertedOrderIds = []; + for (let i = 0; i < testEntitiesCount; i++) { + const customerId = insertedCustomerIds[i]; + const [orderId] = await knex(firstReferencedTableName).insert({ + customer_id: customerId, + order_date: faker.date.past({ years: 1 }), + status: faker.helpers.arrayElement(['Pending', 'Shipped', 'Delivered', 'Cancelled']), + total_amount: parseFloat(faker.commerce.price({ min: 20, max: 500, dec: 2 })), + }); + insertedOrderIds.push(orderId); + + if (faker.datatype.boolean()) { + secondReferencedTableInserts.push({ + order_id: orderId, + shipped_date: faker.date.recent({ days: 30 }), + carrier: faker.company.name(), + tracking_number: faker.string.uuid(), + }); + } + } + + if (secondReferencedTableInserts.length > 0) { + await knex(secondReferencedTableName).insert(secondReferencedTableInserts); + } + + const mainTableColumnData = await knex(mainTableName).columnInfo(); + const firstReferencedTableColumnData = await knex(firstReferencedTableName).columnInfo(); + const secondReferencedTableColumnData = await knex(secondReferencedTableName).columnInfo(); + + return { + main_table: { + table_name: mainTableName, + column_names: Object.keys(mainTableColumnData), + foreign_key_column_names: [], + binary_column_names: [], + primary_key_column_names: ['customer_id'], + }, + first_referenced_table: { + table_name: firstReferencedTableName, + column_names: Object.keys(firstReferencedTableColumnData), + primary_key_column_names: ['order_id'], + foreign_key_column_names: ['customer_id'], + }, + second_referenced_table: { + table_name: secondReferencedTableName, + column_names: Object.keys(secondReferencedTableColumnData), + primary_key_column_names: ['shipment_id'], + foreign_key_column_names: ['order_id'], + }, + }; }; diff --git a/backend/test/utils/test-utilities/create-test-postgres-tables.ts b/backend/test/utils/test-utilities/create-test-postgres-tables.ts index c7b4a11fd..16dd8c3fd 100644 --- a/backend/test/utils/test-utilities/create-test-postgres-tables.ts +++ b/backend/test/utils/test-utilities/create-test-postgres-tables.ts @@ -2,298 +2,298 @@ import { getTestKnex } from '../get-test-knex.js'; import { faker } from '@faker-js/faker'; export const createTestTablesWithComplexPFKeys = async (connectionParams: any) => { - const connectionParamsCopy = { - ...connectionParams, - }; - if (connectionParams.type === 'mysql') { - connectionParamsCopy.type = 'mysql2'; - } - - const knex = getTestKnex(connectionParamsCopy); - - const mainTableName = 'Orders_Complex'; - const firstReferencedTableName = 'OrderItems_Complex'; - const referencedOnTableName = 'Shipments_Complex'; - - await knex.schema.dropTableIfExists(referencedOnTableName); - await knex.schema.dropTableIfExists(firstReferencedTableName); - await knex.schema.dropTableIfExists(mainTableName); - - // Create main_table - await knex.schema.createTable(mainTableName, (table) => { - table.integer('order_id').notNullable(); - table.integer('customer_id').notNullable(); - table.date('order_date'); - table.string('status', 20); - table.decimal('total_amount', 10, 2); - table.primary(['order_id', 'customer_id']); - }); - - // Create first_referenced_table - const firstReferencedTableQuery = knex.schema.createTable(firstReferencedTableName, (table) => { - table.integer('order_id').notNullable(); - table.integer('customer_id').notNullable(); - table.increments('item_id').primary(); - table.string('product_name', 100); - table.integer('quantity'); - table.decimal('price_per_unit', 10, 2); - table - .foreign(['order_id', 'customer_id']) - .references(['order_id', 'customer_id']) - .inTable(mainTableName) - .onDelete('CASCADE'); - }); - await firstReferencedTableQuery; - - // Create second_referenced_table - await knex.schema.createTable(referencedOnTableName, (table) => { - table.increments('shipment_id').primary(); - table.integer('order_id'); - table.integer('customer_id'); - table.date('shipped_date'); - table.string('carrier', 50); - table.string('tracking_number', 100); - table - .foreign(['order_id', 'customer_id']) - .references(['order_id', 'customer_id']) - .inTable(mainTableName) - .onDelete('SET NULL'); - }); - - // seeding data in test tables - - const testEntitiesCount = 42; - - const mainTableInserts = []; - const firstReferencedTableInserts = []; - const secondReferencedTableInserts = []; - - for (let i = 0; i < testEntitiesCount; i++) { - const orderId = i + 1; - const customerId = 100 + i; - mainTableInserts.push({ - order_id: orderId, - customer_id: customerId, - order_date: faker.date.past({ years: 1 }), - status: faker.helpers.arrayElement(['Pending', 'Shipped', 'Delivered', 'Cancelled']), - total_amount: parseFloat(faker.commerce.price({ min: 20, max: 500, dec: 2 })), - }); - - const itemsCount = faker.number.int({ min: 1, max: 5 }); - for (let j = 0; j < itemsCount; j++) { - firstReferencedTableInserts.push({ - order_id: orderId, - customer_id: customerId, - product_name: faker.commerce.productName(), - quantity: faker.number.int({ min: 1, max: 10 }), - price_per_unit: parseFloat(faker.commerce.price({ min: 5, max: 100, dec: 2 })), - }); - } - - if (faker.datatype.boolean()) { - secondReferencedTableInserts.push({ - order_id: orderId, - customer_id: customerId, - shipped_date: faker.date.recent({ days: 30 }), - carrier: faker.company.name(), - tracking_number: faker.string.uuid(), - }); - } - } - - await knex(mainTableName).insert(mainTableInserts); - await knex(firstReferencedTableName).insert(firstReferencedTableInserts); - await knex(referencedOnTableName).insert(secondReferencedTableInserts); - - // Fetch column info - - const mainTableColumnData = await knex(mainTableName).columnInfo(); - const firstReferencedTableColumnData = await knex(firstReferencedTableName).columnInfo(); - const secondReferencedTableColumnData = await knex(referencedOnTableName).columnInfo(); - - return { - main_table: { - table_name: mainTableName, - column_names: Object.keys(mainTableColumnData), - foreign_key_column_names: [], - binary_column_names: [], - primary_key_column_names: ['order_id', 'customer_id'], - }, - first_referenced_table: { - table_name: firstReferencedTableName, - column_names: Object.keys(firstReferencedTableColumnData), - primary_key_column_names: ['item_id'], - }, - second_referenced_table: { - table_name: referencedOnTableName, - column_names: Object.keys(secondReferencedTableColumnData), - primary_key_column_names: ['shipment_id'], - foreign_key_column_names: [], - }, - }; + const connectionParamsCopy = { + ...connectionParams, + }; + if (connectionParams.type === 'mysql') { + connectionParamsCopy.type = 'mysql2'; + } + + const knex = getTestKnex(connectionParamsCopy); + + const mainTableName = 'Orders_Complex'; + const firstReferencedTableName = 'OrderItems_Complex'; + const referencedOnTableName = 'Shipments_Complex'; + + await knex.schema.dropTableIfExists(referencedOnTableName); + await knex.schema.dropTableIfExists(firstReferencedTableName); + await knex.schema.dropTableIfExists(mainTableName); + + // Create main_table + await knex.schema.createTable(mainTableName, (table) => { + table.integer('order_id').notNullable(); + table.integer('customer_id').notNullable(); + table.date('order_date'); + table.string('status', 20); + table.decimal('total_amount', 10, 2); + table.primary(['order_id', 'customer_id']); + }); + + // Create first_referenced_table + const firstReferencedTableQuery = knex.schema.createTable(firstReferencedTableName, (table) => { + table.integer('order_id').notNullable(); + table.integer('customer_id').notNullable(); + table.increments('item_id').primary(); + table.string('product_name', 100); + table.integer('quantity'); + table.decimal('price_per_unit', 10, 2); + table + .foreign(['order_id', 'customer_id']) + .references(['order_id', 'customer_id']) + .inTable(mainTableName) + .onDelete('CASCADE'); + }); + await firstReferencedTableQuery; + + // Create second_referenced_table + await knex.schema.createTable(referencedOnTableName, (table) => { + table.increments('shipment_id').primary(); + table.integer('order_id'); + table.integer('customer_id'); + table.date('shipped_date'); + table.string('carrier', 50); + table.string('tracking_number', 100); + table + .foreign(['order_id', 'customer_id']) + .references(['order_id', 'customer_id']) + .inTable(mainTableName) + .onDelete('SET NULL'); + }); + + // seeding data in test tables + + const testEntitiesCount = 42; + + const mainTableInserts = []; + const firstReferencedTableInserts = []; + const secondReferencedTableInserts = []; + + for (let i = 0; i < testEntitiesCount; i++) { + const orderId = i + 1; + const customerId = 100 + i; + mainTableInserts.push({ + order_id: orderId, + customer_id: customerId, + order_date: faker.date.past({ years: 1 }), + status: faker.helpers.arrayElement(['Pending', 'Shipped', 'Delivered', 'Cancelled']), + total_amount: parseFloat(faker.commerce.price({ min: 20, max: 500, dec: 2 })), + }); + + const itemsCount = faker.number.int({ min: 1, max: 5 }); + for (let j = 0; j < itemsCount; j++) { + firstReferencedTableInserts.push({ + order_id: orderId, + customer_id: customerId, + product_name: faker.commerce.productName(), + quantity: faker.number.int({ min: 1, max: 10 }), + price_per_unit: parseFloat(faker.commerce.price({ min: 5, max: 100, dec: 2 })), + }); + } + + if (faker.datatype.boolean()) { + secondReferencedTableInserts.push({ + order_id: orderId, + customer_id: customerId, + shipped_date: faker.date.recent({ days: 30 }), + carrier: faker.company.name(), + tracking_number: faker.string.uuid(), + }); + } + } + + await knex(mainTableName).insert(mainTableInserts); + await knex(firstReferencedTableName).insert(firstReferencedTableInserts); + await knex(referencedOnTableName).insert(secondReferencedTableInserts); + + // Fetch column info + + const mainTableColumnData = await knex(mainTableName).columnInfo(); + const firstReferencedTableColumnData = await knex(firstReferencedTableName).columnInfo(); + const secondReferencedTableColumnData = await knex(referencedOnTableName).columnInfo(); + + return { + main_table: { + table_name: mainTableName, + column_names: Object.keys(mainTableColumnData), + foreign_key_column_names: [], + binary_column_names: [], + primary_key_column_names: ['order_id', 'customer_id'], + }, + first_referenced_table: { + table_name: firstReferencedTableName, + column_names: Object.keys(firstReferencedTableColumnData), + primary_key_column_names: ['item_id'], + }, + second_referenced_table: { + table_name: referencedOnTableName, + column_names: Object.keys(secondReferencedTableColumnData), + primary_key_column_names: ['shipment_id'], + foreign_key_column_names: [], + }, + }; }; export const createTestTablesWithSimplePFKeys = async (connectionParams: any) => { - const connectionParamsCopy = { - ...connectionParams, - }; - if (connectionParams.type === 'mysql') { - connectionParamsCopy.type = 'mysql2'; - } - - const knex = getTestKnex(connectionParamsCopy); - - // -- Table 1: Customers (simple primary key) - // CREATE TABLE customers ( - // customer_id SERIAL PRIMARY KEY, - // name VARCHAR(100), - // email VARCHAR(100), - // created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP - // ); - - // -- Table 2: Orders (foreign key to Customers) - // CREATE TABLE orders ( - // order_id SERIAL PRIMARY KEY, - // customer_id INT, - // order_date DATE, - // status VARCHAR(20), - // total_amount DECIMAL(10, 2), - // FOREIGN KEY (customer_id) - // REFERENCES customers(customer_id) - // ON DELETE CASCADE - // ); - - // -- Table 3: Shipments (foreign key to Orders) - // CREATE TABLE shipments ( - // shipment_id SERIAL PRIMARY KEY, - // order_id INT, - // shipped_date DATE, - // carrier VARCHAR(50), - // tracking_number VARCHAR(100), - // FOREIGN KEY (order_id) - // REFERENCES orders(order_id) - // ON DELETE SET NULL - // ); - - const mainTableName = 'Customers_Simple'; - const firstReferencedTableName = 'Orders_Simple'; - const secondReferencedTableName = 'Shipments_Simple'; - - await knex.schema.dropTableIfExists(secondReferencedTableName); - await knex.schema.dropTableIfExists(firstReferencedTableName); - await knex.schema.dropTableIfExists(mainTableName); - - // Create main_table - await knex.schema.createTable(mainTableName, (table) => { - table.increments('customer_id').primary(); - table.string('name', 100); - table.string('email', 100); - table.timestamp('created_at').defaultTo(knex.fn.now()); - }); - - // Create first_referenced_table - await knex.schema.createTable(firstReferencedTableName, (table) => { - table.increments('order_id').primary(); - table.integer('customer_id').notNullable(); - table.date('order_date'); - table.string('status', 20); - table.decimal('total_amount', 10, 2); - table.foreign('customer_id').references('customer_id').inTable(mainTableName).onDelete('CASCADE'); - }); - - // Create second_referenced_table - await knex.schema.createTable(secondReferencedTableName, (table) => { - table.increments('shipment_id').primary(); - table.integer('order_id'); - table.date('shipped_date'); - table.string('carrier', 50); - table.string('tracking_number', 100); - table.foreign('order_id').references('order_id').inTable(firstReferencedTableName).onDelete('SET NULL'); - }); - - // seeding data in test tables - - const testEntitiesCount = 42; - - const mainTableInserts = []; - const firstReferencedTableInserts = []; - const secondReferencedTableInserts = []; - - for (let i = 0; i < testEntitiesCount; i++) { - mainTableInserts.push({ - name: faker.person.fullName(), - email: faker.internet.email(), - }); - } - - const insertedCustomerIds = await knex(mainTableName).insert(mainTableInserts).returning('customer_id'); - - for (let i = 0; i < testEntitiesCount; i++) { - const customerId = Array.isArray(insertedCustomerIds) - ? typeof insertedCustomerIds[i] === 'object' - ? (insertedCustomerIds[i] as any).customer_id - : insertedCustomerIds[i] - : insertedCustomerIds; - const orderId = i + 1; - firstReferencedTableInserts.push({ - customer_id: customerId, - order_date: faker.date.past({ years: 1 }), - status: faker.helpers.arrayElement(['Pending', 'Shipped', 'Delivered', 'Cancelled']), - total_amount: parseFloat(faker.commerce.price({ min: 20, max: 500, dec: 2 })), - }); - - if (faker.datatype.boolean()) { - secondReferencedTableInserts.push({ - order_id: orderId, - shipped_date: faker.date.recent({ days: 30 }), - carrier: faker.company.name(), - tracking_number: faker.string.uuid(), - }); - } - } - - const insertedOrderIds = await knex(firstReferencedTableName) - .insert(firstReferencedTableInserts) - .returning('order_id'); - - // Adjust order_id in shipments to match inserted orders - for (let i = 0; i < secondReferencedTableInserts.length; i++) { - if (insertedOrderIds[i]) { - secondReferencedTableInserts[i].order_id = Array.isArray(insertedOrderIds) - ? typeof insertedOrderIds[i] === 'object' - ? (insertedOrderIds[i] as any).order_id - : insertedOrderIds[i] - : insertedOrderIds; - } - } - - await knex(secondReferencedTableName).insert(secondReferencedTableInserts); - - // Fetch column info - - const mainTableColumnData = await knex(mainTableName).columnInfo(); - const firstReferencedTableColumnData = await knex(firstReferencedTableName).columnInfo(); - const secondReferencedTableColumnData = await knex(secondReferencedTableName).columnInfo(); - - return { - main_table: { - table_name: mainTableName, - column_names: Object.keys(mainTableColumnData), - foreign_key_column_names: [], - binary_column_names: [], - primary_key_column_names: ['customer_id'], - }, - first_referenced_table: { - table_name: firstReferencedTableName, - column_names: Object.keys(firstReferencedTableColumnData), - primary_key_column_names: ['order_id'], - foreign_key_column_names: ['customer_id'], - }, - second_referenced_table: { - table_name: secondReferencedTableName, - column_names: Object.keys(secondReferencedTableColumnData), - primary_key_column_names: ['shipment_id'], - foreign_key_column_names: ['order_id'], - }, - }; + const connectionParamsCopy = { + ...connectionParams, + }; + if (connectionParams.type === 'mysql') { + connectionParamsCopy.type = 'mysql2'; + } + + const knex = getTestKnex(connectionParamsCopy); + + // -- Table 1: Customers (simple primary key) + // CREATE TABLE customers ( + // customer_id SERIAL PRIMARY KEY, + // name VARCHAR(100), + // email VARCHAR(100), + // created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + // ); + + // -- Table 2: Orders (foreign key to Customers) + // CREATE TABLE orders ( + // order_id SERIAL PRIMARY KEY, + // customer_id INT, + // order_date DATE, + // status VARCHAR(20), + // total_amount DECIMAL(10, 2), + // FOREIGN KEY (customer_id) + // REFERENCES customers(customer_id) + // ON DELETE CASCADE + // ); + + // -- Table 3: Shipments (foreign key to Orders) + // CREATE TABLE shipments ( + // shipment_id SERIAL PRIMARY KEY, + // order_id INT, + // shipped_date DATE, + // carrier VARCHAR(50), + // tracking_number VARCHAR(100), + // FOREIGN KEY (order_id) + // REFERENCES orders(order_id) + // ON DELETE SET NULL + // ); + + const mainTableName = 'Customers_Simple'; + const firstReferencedTableName = 'Orders_Simple'; + const secondReferencedTableName = 'Shipments_Simple'; + + await knex.schema.dropTableIfExists(secondReferencedTableName); + await knex.schema.dropTableIfExists(firstReferencedTableName); + await knex.schema.dropTableIfExists(mainTableName); + + // Create main_table + await knex.schema.createTable(mainTableName, (table) => { + table.increments('customer_id').primary(); + table.string('name', 100); + table.string('email', 100); + table.timestamp('created_at').defaultTo(knex.fn.now()); + }); + + // Create first_referenced_table + await knex.schema.createTable(firstReferencedTableName, (table) => { + table.increments('order_id').primary(); + table.integer('customer_id').notNullable(); + table.date('order_date'); + table.string('status', 20); + table.decimal('total_amount', 10, 2); + table.foreign('customer_id').references('customer_id').inTable(mainTableName).onDelete('CASCADE'); + }); + + // Create second_referenced_table + await knex.schema.createTable(secondReferencedTableName, (table) => { + table.increments('shipment_id').primary(); + table.integer('order_id'); + table.date('shipped_date'); + table.string('carrier', 50); + table.string('tracking_number', 100); + table.foreign('order_id').references('order_id').inTable(firstReferencedTableName).onDelete('SET NULL'); + }); + + // seeding data in test tables + + const testEntitiesCount = 42; + + const mainTableInserts = []; + const firstReferencedTableInserts = []; + const secondReferencedTableInserts = []; + + for (let i = 0; i < testEntitiesCount; i++) { + mainTableInserts.push({ + name: faker.person.fullName(), + email: faker.internet.email(), + }); + } + + const insertedCustomerIds = await knex(mainTableName).insert(mainTableInserts).returning('customer_id'); + + for (let i = 0; i < testEntitiesCount; i++) { + const customerId = Array.isArray(insertedCustomerIds) + ? typeof insertedCustomerIds[i] === 'object' + ? (insertedCustomerIds[i] as any).customer_id + : insertedCustomerIds[i] + : insertedCustomerIds; + const orderId = i + 1; + firstReferencedTableInserts.push({ + customer_id: customerId, + order_date: faker.date.past({ years: 1 }), + status: faker.helpers.arrayElement(['Pending', 'Shipped', 'Delivered', 'Cancelled']), + total_amount: parseFloat(faker.commerce.price({ min: 20, max: 500, dec: 2 })), + }); + + if (faker.datatype.boolean()) { + secondReferencedTableInserts.push({ + order_id: orderId, + shipped_date: faker.date.recent({ days: 30 }), + carrier: faker.company.name(), + tracking_number: faker.string.uuid(), + }); + } + } + + const insertedOrderIds = await knex(firstReferencedTableName) + .insert(firstReferencedTableInserts) + .returning('order_id'); + + // Adjust order_id in shipments to match inserted orders + for (let i = 0; i < secondReferencedTableInserts.length; i++) { + if (insertedOrderIds[i]) { + secondReferencedTableInserts[i].order_id = Array.isArray(insertedOrderIds) + ? typeof insertedOrderIds[i] === 'object' + ? (insertedOrderIds[i] as any).order_id + : insertedOrderIds[i] + : insertedOrderIds; + } + } + + await knex(secondReferencedTableName).insert(secondReferencedTableInserts); + + // Fetch column info + + const mainTableColumnData = await knex(mainTableName).columnInfo(); + const firstReferencedTableColumnData = await knex(firstReferencedTableName).columnInfo(); + const secondReferencedTableColumnData = await knex(secondReferencedTableName).columnInfo(); + + return { + main_table: { + table_name: mainTableName, + column_names: Object.keys(mainTableColumnData), + foreign_key_column_names: [], + binary_column_names: [], + primary_key_column_names: ['customer_id'], + }, + first_referenced_table: { + table_name: firstReferencedTableName, + column_names: Object.keys(firstReferencedTableColumnData), + primary_key_column_names: ['order_id'], + foreign_key_column_names: ['customer_id'], + }, + second_referenced_table: { + table_name: secondReferencedTableName, + column_names: Object.keys(secondReferencedTableColumnData), + primary_key_column_names: ['shipment_id'], + foreign_key_column_names: ['order_id'], + }, + }; }; diff --git a/backend/test/utils/test.utils.ts b/backend/test/utils/test.utils.ts index ee3f2971b..14067efae 100644 --- a/backend/test/utils/test.utils.ts +++ b/backend/test/utils/test.utils.ts @@ -6,101 +6,101 @@ import { SchedulerRegistry } from '@nestjs/schedule'; @Injectable() export class TestUtils { - databaseService: DatabaseService; - schedulerRegistry: SchedulerRegistry; + databaseService: DatabaseService; + schedulerRegistry: SchedulerRegistry; - constructor(databaseService: DatabaseService, schedulerRegistry: SchedulerRegistry) { - if (process.env.NODE_ENV !== 'test') { - throw new Error('ERROR-TEST-UTILS-ONLY-FOR-TESTS'); - } - this.databaseService = databaseService; - this.schedulerRegistry = schedulerRegistry; - } + constructor(databaseService: DatabaseService, schedulerRegistry: SchedulerRegistry) { + if (process.env.NODE_ENV !== 'test') { + throw new Error('ERROR-TEST-UTILS-ONLY-FOR-TESTS'); + } + this.databaseService = databaseService; + this.schedulerRegistry = schedulerRegistry; + } - async shutdownServer(server) { - try { - await server.httpServer.close(); - await this.closeDbConnection(); - } catch (e) { - console.log('shutdown server error ->', e); - } - } + async shutdownServer(server) { + try { + await server.httpServer.close(); + await this.closeDbConnection(); + } catch (e) { + console.log('shutdown server error ->', e); + } + } - public clearCrons(): void { - try { - const jobs = this.schedulerRegistry.getCronJobs(); - jobs.forEach((job, jobName) => { - job.stop(); - this.schedulerRegistry.deleteCronJob(jobName); - }); - } catch (e) { - console.log('clear cron error ->', e); - } - } + public clearCrons(): void { + try { + const jobs = this.schedulerRegistry.getCronJobs(); + jobs.forEach((job, jobName) => { + job.stop(); + this.schedulerRegistry.deleteCronJob(jobName); + }); + } catch (e) { + console.log('clear cron error ->', e); + } + } - static getJwtTokenFromResponse(res: any): string { - let jwt: string = res.headers['set-cookie'][0]; - jwt = jwt.replace('rocketadmin_cookie=', ''); - jwt = jwt.replace('; Path=/', ''); - return jwt; - } + static getJwtTokenFromResponse(res: any): string { + let jwt: string = res.headers['set-cookie'][0]; + jwt = jwt.replace('rocketadmin_cookie=', ''); + jwt = jwt.replace('; Path=/', ''); + return jwt; + } - verifyJwtToken(token: string): { - sub: string; - email: string; - exp: number; - iat: number; - } { - const tokenValue = token.split('=')[1].split(';')[0]; - const jwtSecret = process.env.JWT_SECRET; - const data = jwt.verify(tokenValue, jwtSecret) as jwt.JwtPayload; - return { - sub: data.id, - email: data.email, - exp: data.exp, - iat: data.iat, - }; - } + verifyJwtToken(token: string): { + sub: string; + email: string; + exp: number; + iat: number; + } { + const tokenValue = token.split('=')[1].split(';')[0]; + const jwtSecret = process.env.JWT_SECRET; + const data = jwt.verify(tokenValue, jwtSecret) as jwt.JwtPayload; + return { + sub: data.id, + email: data.email, + exp: data.exp, + iat: data.iat, + }; + } - static getJwtTokenFromResponse2(res: any): string { - let jwt: string = res.headers.get('set-cookie'); - jwt = jwt.replace('rocketadmin_cookie=', ''); - jwt = jwt.replace('; Path=/', ''); - return jwt; - } + static getJwtTokenFromResponse2(res: any): string { + let jwt: string = res.headers.get('set-cookie'); + jwt = jwt.replace('rocketadmin_cookie=', ''); + jwt = jwt.replace('; Path=/', ''); + return jwt; + } - async closeDbConnection() { - try { - this.databaseService.closeConnection(); - } catch (e) { - console.log('close db connection error ->', e); - } - } + async closeDbConnection() { + try { + this.databaseService.closeConnection(); + } catch (e) { + console.log('close db connection error ->', e); + } + } - async resetDb() { - try { - // const entities = await this.getEntities(); - await this.databaseService.dropDatabase(); - //await this.addMockEntities(); - } catch (e) { - console.log('reset db error ->', e); - } - } + async resetDb() { + try { + // const entities = await this.getEntities(); + await this.databaseService.dropDatabase(); + //await this.addMockEntities(); + } catch (e) { + console.log('reset db error ->', e); + } + } - sleep(ms = 1000): Promise { - return new Promise((resolve) => { - setTimeout(() => { - resolve(); - }, ms); - }); - } + sleep(ms = 1000): Promise { + return new Promise((resolve) => { + setTimeout(() => { + resolve(); + }, ms); + }); + } - // private async addMockEntities() { - // const newMockEntity = new MockEntity(); - // newMockEntity.textField = faker.lorem.words(1); - // newMockEntity.booleanField = faker.datatype.boolean(); - // newMockEntity.integerField = faker.number.int({ min: 5, max: 10, precision: 1 }); - // const repository = await this.databaseService.getRepository('MockEntity'); - // await repository.save(newMockEntity); - // } + // private async addMockEntities() { + // const newMockEntity = new MockEntity(); + // newMockEntity.textField = faker.lorem.words(1); + // newMockEntity.booleanField = faker.datatype.boolean(); + // newMockEntity.integerField = faker.number.int({ min: 5, max: 10, precision: 1 }); + // const repository = await this.databaseService.getRepository('MockEntity'); + // await repository.save(newMockEntity); + // } } diff --git a/backend/test/utils/user-with-different-permissions-utils.ts b/backend/test/utils/user-with-different-permissions-utils.ts index 215e56309..657eae10d 100644 --- a/backend/test/utils/user-with-different-permissions-utils.ts +++ b/backend/test/utils/user-with-different-permissions-utils.ts @@ -5,561 +5,561 @@ import { AccessLevelEnum } from '../../src/enums/index.js'; import { MockFactory } from '../mock.factory.js'; import { CreatedTableInfo, createTestTable } from './create-test-table.js'; import { - inviteUserInCompanyAndAcceptInvitation, - registerUserAndReturnUserInfo, + inviteUserInCompanyAndAcceptInvitation, + registerUserAndReturnUserInfo, } from './register-user-and-return-user-info.js'; export async function createConnectionsAndInviteNewUserInNewGroupWithGroupPermissions( - app: INestApplication, - invitedUserEmail?: string, + app: INestApplication, + invitedUserEmail?: string, ): Promise { - const connectionsId = { - firstId: null, - secondId: null, - firstAdminGroupId: null, - }; - - const mockFactory = new MockFactory(); - const connectionAdminUserInfo = await registerUserAndReturnUserInfo(app); - const simpleUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - connectionAdminUserInfo.token, - undefined, - app, - undefined, - invitedUserEmail, - ); - const connectionAdminUserToken = connectionAdminUserInfo.token; - const simpleUserToken = simpleUserRegisterInfo.token; - - const newConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); - const newConnection2 = mockFactory.generateConnectionToTestMySQLDBInDocker(); - const newGroup1 = mockFactory.generateCreateGroupDto1(); - const firstTable = await createTestTable(newConnection); - const secondTable = await createTestTable(newConnection2); - - const tablePermissions = { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: false, - }; - - const createFirstConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .set('Cookie', connectionAdminUserToken) - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createFirstConnectionRO = JSON.parse(createFirstConnectionResponse.text); - connectionsId.firstId = createFirstConnectionRO.id; - - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connectionsId.firstId}`) - .set('Cookie', connectionAdminUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - - const firstAdminGroupId = getGroupsRO[0].group.id; - - const createSecondConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .set('Cookie', connectionAdminUserToken) - .send(newConnection2) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createSecondConnectionRO = JSON.parse(createSecondConnectionResponse.text); - connectionsId.secondId = createSecondConnectionRO.id; - const email = simpleUserRegisterInfo.email; - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connectionsId.firstId}`) - .set('Cookie', connectionAdminUserToken) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const groupId = JSON.parse(createGroupResponse.text).id; - - const permissions = { - connection: { - connectionId: connectionsId.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: groupId, - accessLevel: AccessLevelEnum.edit, - }, - tables: [ - { - tableName: firstTable.testTableName, - accessLevel: tablePermissions, - }, - ], - }; - - const _createOrUpdatePermissionResponse = await request(app.getHttpServer()) - .put(`/permissions/${groupId}?connectionId=${connectionsId.firstId}`) - .send({ permissions }) - .set('Cookie', connectionAdminUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - await request(app.getHttpServer()) - .put('/group/user') - .set('Cookie', connectionAdminUserToken) - .send({ groupId, email }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - return { - firstTableInfo: firstTable, - secondTableInfo: secondTable, - permissions: { - table: { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: false, - }, - }, - connections: { - firstId: connectionsId.firstId, - secondId: connectionsId.secondId, - }, - groups: { - firstAdminGroupId: firstAdminGroupId, - secondAdminGroupId: null, - createdGroupId: groupId, - }, - users: { - adminUserToken: connectionAdminUserToken, - simpleUserToken: simpleUserToken, - simpleUserEmail: simpleUserRegisterInfo.email, - adminUserEmail: connectionAdminUserInfo.email, - adminUserPassword: connectionAdminUserInfo.password, - simpleUserPassword: simpleUserRegisterInfo.password, - }, - }; + const connectionsId = { + firstId: null, + secondId: null, + firstAdminGroupId: null, + }; + + const mockFactory = new MockFactory(); + const connectionAdminUserInfo = await registerUserAndReturnUserInfo(app); + const simpleUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + connectionAdminUserInfo.token, + undefined, + app, + undefined, + invitedUserEmail, + ); + const connectionAdminUserToken = connectionAdminUserInfo.token; + const simpleUserToken = simpleUserRegisterInfo.token; + + const newConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); + const newConnection2 = mockFactory.generateConnectionToTestMySQLDBInDocker(); + const newGroup1 = mockFactory.generateCreateGroupDto1(); + const firstTable = await createTestTable(newConnection); + const secondTable = await createTestTable(newConnection2); + + const tablePermissions = { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: false, + }; + + const createFirstConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .set('Cookie', connectionAdminUserToken) + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createFirstConnectionRO = JSON.parse(createFirstConnectionResponse.text); + connectionsId.firstId = createFirstConnectionRO.id; + + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connectionsId.firstId}`) + .set('Cookie', connectionAdminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + + const firstAdminGroupId = getGroupsRO[0].group.id; + + const createSecondConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .set('Cookie', connectionAdminUserToken) + .send(newConnection2) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createSecondConnectionRO = JSON.parse(createSecondConnectionResponse.text); + connectionsId.secondId = createSecondConnectionRO.id; + const email = simpleUserRegisterInfo.email; + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connectionsId.firstId}`) + .set('Cookie', connectionAdminUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const groupId = JSON.parse(createGroupResponse.text).id; + + const permissions = { + connection: { + connectionId: connectionsId.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: groupId, + accessLevel: AccessLevelEnum.edit, + }, + tables: [ + { + tableName: firstTable.testTableName, + accessLevel: tablePermissions, + }, + ], + }; + + const _createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${groupId}?connectionId=${connectionsId.firstId}`) + .send({ permissions }) + .set('Cookie', connectionAdminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', connectionAdminUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + return { + firstTableInfo: firstTable, + secondTableInfo: secondTable, + permissions: { + table: { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: false, + }, + }, + connections: { + firstId: connectionsId.firstId, + secondId: connectionsId.secondId, + }, + groups: { + firstAdminGroupId: firstAdminGroupId, + secondAdminGroupId: null, + createdGroupId: groupId, + }, + users: { + adminUserToken: connectionAdminUserToken, + simpleUserToken: simpleUserToken, + simpleUserEmail: simpleUserRegisterInfo.email, + adminUserEmail: connectionAdminUserInfo.email, + adminUserPassword: connectionAdminUserInfo.password, + simpleUserPassword: simpleUserRegisterInfo.password, + }, + }; } export async function createConnectionsAndInviteNewUserInNewGroupWithOnlyTablePermissions( - app: INestApplication, + app: INestApplication, ): Promise { - const connectionsId = { - firstId: null, - secondId: null, - firstAdminGroupId: null, - }; - - const mockFactory = new MockFactory(); - const connectionAdminUserInfo = await registerUserAndReturnUserInfo(app); - const simpleUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - connectionAdminUserInfo.token, - undefined, - app, - undefined, - ); - const connectionAdminUserToken = connectionAdminUserInfo.token; - const simpleUserToken = simpleUserRegisterInfo.token; - - const newConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); - const newConnection2 = mockFactory.generateConnectionToTestMySQLDBInDocker(); - const newGroup1 = mockFactory.generateCreateGroupDto1(); - const firstTable = await createTestTable(newConnection); - const secondTable = await createTestTable(newConnection2); - - const tablePermissions = { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: false, - }; - - const createFirstConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .set('Cookie', connectionAdminUserToken) - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createFirstConnectionRO = JSON.parse(createFirstConnectionResponse.text); - connectionsId.firstId = createFirstConnectionRO.id; - - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connectionsId.firstId}`) - .set('Cookie', connectionAdminUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - - const firstAdminGroupId = getGroupsRO[0].group.id; - - const createSecondConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .set('Cookie', connectionAdminUserToken) - .send(newConnection2) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createSecondConnectionRO = JSON.parse(createSecondConnectionResponse.text); - connectionsId.secondId = createSecondConnectionRO.id; - const email = simpleUserRegisterInfo.email; - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connectionsId.firstId}`) - .set('Cookie', connectionAdminUserToken) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const groupId = JSON.parse(createGroupResponse.text).id; - - const permissions = { - connection: { - connectionId: connectionsId.firstId, - accessLevel: AccessLevelEnum.none, - }, - group: { - groupId: groupId, - accessLevel: AccessLevelEnum.none, - }, - tables: [ - { - tableName: firstTable.testTableName, - accessLevel: tablePermissions, - }, - ], - }; - - const _createOrUpdatePermissionResponse = await request(app.getHttpServer()) - .put(`/permissions/${groupId}?connectionId=${connectionsId.firstId}`) - .send({ permissions }) - .set('Cookie', connectionAdminUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - const addUserResult = await request(app.getHttpServer()) - .put('/group/user') - .set('Cookie', connectionAdminUserToken) - .send({ groupId, email }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const addUserRO = JSON.parse(addUserResult.text); - if (addUserResult.status > 201) { - console.error('addUserResult.body -> ', addUserRO); - } - - return { - firstTableInfo: firstTable, - secondTableInfo: secondTable, - permissions: { - table: { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: false, - }, - }, - connections: { - firstId: connectionsId.firstId, - secondId: connectionsId.secondId, - }, - groups: { - firstAdminGroupId: firstAdminGroupId, - secondAdminGroupId: null, - createdGroupId: groupId, - }, - users: { - adminUserToken: connectionAdminUserToken, - simpleUserToken: simpleUserToken, - simpleUserEmail: simpleUserRegisterInfo.email, - adminUserEmail: connectionAdminUserInfo.email, - adminUserPassword: connectionAdminUserInfo.password, - simpleUserPassword: simpleUserRegisterInfo.password, - }, - }; + const connectionsId = { + firstId: null, + secondId: null, + firstAdminGroupId: null, + }; + + const mockFactory = new MockFactory(); + const connectionAdminUserInfo = await registerUserAndReturnUserInfo(app); + const simpleUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + connectionAdminUserInfo.token, + undefined, + app, + undefined, + ); + const connectionAdminUserToken = connectionAdminUserInfo.token; + const simpleUserToken = simpleUserRegisterInfo.token; + + const newConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); + const newConnection2 = mockFactory.generateConnectionToTestMySQLDBInDocker(); + const newGroup1 = mockFactory.generateCreateGroupDto1(); + const firstTable = await createTestTable(newConnection); + const secondTable = await createTestTable(newConnection2); + + const tablePermissions = { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: false, + }; + + const createFirstConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .set('Cookie', connectionAdminUserToken) + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createFirstConnectionRO = JSON.parse(createFirstConnectionResponse.text); + connectionsId.firstId = createFirstConnectionRO.id; + + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connectionsId.firstId}`) + .set('Cookie', connectionAdminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + + const firstAdminGroupId = getGroupsRO[0].group.id; + + const createSecondConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .set('Cookie', connectionAdminUserToken) + .send(newConnection2) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createSecondConnectionRO = JSON.parse(createSecondConnectionResponse.text); + connectionsId.secondId = createSecondConnectionRO.id; + const email = simpleUserRegisterInfo.email; + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connectionsId.firstId}`) + .set('Cookie', connectionAdminUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const groupId = JSON.parse(createGroupResponse.text).id; + + const permissions = { + connection: { + connectionId: connectionsId.firstId, + accessLevel: AccessLevelEnum.none, + }, + group: { + groupId: groupId, + accessLevel: AccessLevelEnum.none, + }, + tables: [ + { + tableName: firstTable.testTableName, + accessLevel: tablePermissions, + }, + ], + }; + + const _createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${groupId}?connectionId=${connectionsId.firstId}`) + .send({ permissions }) + .set('Cookie', connectionAdminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + const addUserResult = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', connectionAdminUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const addUserRO = JSON.parse(addUserResult.text); + if (addUserResult.status > 201) { + console.error('addUserResult.body -> ', addUserRO); + } + + return { + firstTableInfo: firstTable, + secondTableInfo: secondTable, + permissions: { + table: { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: false, + }, + }, + connections: { + firstId: connectionsId.firstId, + secondId: connectionsId.secondId, + }, + groups: { + firstAdminGroupId: firstAdminGroupId, + secondAdminGroupId: null, + createdGroupId: groupId, + }, + users: { + adminUserToken: connectionAdminUserToken, + simpleUserToken: simpleUserToken, + simpleUserEmail: simpleUserRegisterInfo.email, + adminUserEmail: connectionAdminUserInfo.email, + adminUserPassword: connectionAdminUserInfo.password, + simpleUserPassword: simpleUserRegisterInfo.password, + }, + }; } export type TablePermissions = { - visibility: boolean; - readonly: boolean; - add: boolean; - delete: boolean; - edit: boolean; + visibility: boolean; + readonly: boolean; + add: boolean; + delete: boolean; + edit: boolean; }; export async function createConnectionsAndInviteNewUserInNewGroupWithTableDifferentConnectionGroupReadOnlyPermissions( - app: INestApplication, - tablePermissions: TablePermissions | null = null, + app: INestApplication, + tablePermissions: TablePermissions | null = null, ): Promise { - if (!tablePermissions) { - tablePermissions = { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: false, - }; - } - - const connectionsId = { - firstId: null, - secondId: null, - firstAdminGroupId: null, - }; - - const mockFactory = new MockFactory(); - const connectionAdminUserInfo = await registerUserAndReturnUserInfo(app); - const simpleUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - connectionAdminUserInfo.token, - undefined, - app, - undefined, - ); - const connectionAdminUserToken = connectionAdminUserInfo.token; - const simpleUserToken = simpleUserRegisterInfo.token; - - const newConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); - const newConnection2 = mockFactory.generateConnectionToTestMySQLDBInDocker(); - const newGroup1 = mockFactory.generateCreateGroupDto1(); - const firstTable = await createTestTable(newConnection); - const secondTable = await createTestTable(newConnection2); - - const createFirstConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .set('Cookie', connectionAdminUserToken) - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createFirstConnectionRO = JSON.parse(createFirstConnectionResponse.text); - connectionsId.firstId = createFirstConnectionRO.id; - - const getGroupsResponse = await request(app.getHttpServer()) - .get(`/connection/groups/${connectionsId.firstId}`) - .set('Cookie', connectionAdminUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const getGroupsRO = JSON.parse(getGroupsResponse.text); - - const firstAdminGroupId = getGroupsRO[0].group.id; - - const createSecondConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .set('Cookie', connectionAdminUserToken) - .send(newConnection2) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const createSecondConnectionRO = JSON.parse(createSecondConnectionResponse.text); - connectionsId.secondId = createSecondConnectionRO.id; - const email = simpleUserRegisterInfo.email; - - const createGroupResponse = await request(app.getHttpServer()) - .post(`/connection/group/${connectionsId.firstId}`) - .set('Cookie', connectionAdminUserToken) - .send(newGroup1) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const groupId = JSON.parse(createGroupResponse.text).id; - - const permissions = { - connection: { - connectionId: connectionsId.firstId, - accessLevel: AccessLevelEnum.readonly, - }, - group: { - groupId: groupId, - accessLevel: AccessLevelEnum.readonly, - }, - tables: [ - { - tableName: firstTable.testTableName, - accessLevel: tablePermissions, - }, - ], - }; - - const _createOrUpdatePermissionResponse = await request(app.getHttpServer()) - .put(`/permissions/${groupId}?connectionId=${connectionsId.firstId}`) - .send({ permissions }) - .set('Cookie', connectionAdminUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - await request(app.getHttpServer()) - .put('/group/user') - .set('Cookie', connectionAdminUserToken) - .send({ groupId, email }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - return { - firstTableInfo: firstTable, - secondTableInfo: secondTable, - permissions: { - table: { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: false, - }, - }, - connections: { - firstId: connectionsId.firstId, - secondId: connectionsId.secondId, - }, - groups: { - firstAdminGroupId: firstAdminGroupId, - secondAdminGroupId: null, - createdGroupId: groupId, - }, - users: { - adminUserToken: connectionAdminUserToken, - simpleUserToken: simpleUserToken, - simpleUserEmail: simpleUserRegisterInfo.email, - adminUserEmail: connectionAdminUserInfo.email, - adminUserPassword: connectionAdminUserInfo.password, - simpleUserPassword: simpleUserRegisterInfo.password, - }, - }; + if (!tablePermissions) { + tablePermissions = { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: false, + }; + } + + const connectionsId = { + firstId: null, + secondId: null, + firstAdminGroupId: null, + }; + + const mockFactory = new MockFactory(); + const connectionAdminUserInfo = await registerUserAndReturnUserInfo(app); + const simpleUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + connectionAdminUserInfo.token, + undefined, + app, + undefined, + ); + const connectionAdminUserToken = connectionAdminUserInfo.token; + const simpleUserToken = simpleUserRegisterInfo.token; + + const newConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); + const newConnection2 = mockFactory.generateConnectionToTestMySQLDBInDocker(); + const newGroup1 = mockFactory.generateCreateGroupDto1(); + const firstTable = await createTestTable(newConnection); + const secondTable = await createTestTable(newConnection2); + + const createFirstConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .set('Cookie', connectionAdminUserToken) + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createFirstConnectionRO = JSON.parse(createFirstConnectionResponse.text); + connectionsId.firstId = createFirstConnectionRO.id; + + const getGroupsResponse = await request(app.getHttpServer()) + .get(`/connection/groups/${connectionsId.firstId}`) + .set('Cookie', connectionAdminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const getGroupsRO = JSON.parse(getGroupsResponse.text); + + const firstAdminGroupId = getGroupsRO[0].group.id; + + const createSecondConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .set('Cookie', connectionAdminUserToken) + .send(newConnection2) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const createSecondConnectionRO = JSON.parse(createSecondConnectionResponse.text); + connectionsId.secondId = createSecondConnectionRO.id; + const email = simpleUserRegisterInfo.email; + + const createGroupResponse = await request(app.getHttpServer()) + .post(`/connection/group/${connectionsId.firstId}`) + .set('Cookie', connectionAdminUserToken) + .send(newGroup1) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const groupId = JSON.parse(createGroupResponse.text).id; + + const permissions = { + connection: { + connectionId: connectionsId.firstId, + accessLevel: AccessLevelEnum.readonly, + }, + group: { + groupId: groupId, + accessLevel: AccessLevelEnum.readonly, + }, + tables: [ + { + tableName: firstTable.testTableName, + accessLevel: tablePermissions, + }, + ], + }; + + const _createOrUpdatePermissionResponse = await request(app.getHttpServer()) + .put(`/permissions/${groupId}?connectionId=${connectionsId.firstId}`) + .send({ permissions }) + .set('Cookie', connectionAdminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', connectionAdminUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + return { + firstTableInfo: firstTable, + secondTableInfo: secondTable, + permissions: { + table: { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: false, + }, + }, + connections: { + firstId: connectionsId.firstId, + secondId: connectionsId.secondId, + }, + groups: { + firstAdminGroupId: firstAdminGroupId, + secondAdminGroupId: null, + createdGroupId: groupId, + }, + users: { + adminUserToken: connectionAdminUserToken, + simpleUserToken: simpleUserToken, + simpleUserEmail: simpleUserRegisterInfo.email, + adminUserEmail: connectionAdminUserInfo.email, + adminUserPassword: connectionAdminUserInfo.password, + simpleUserPassword: simpleUserRegisterInfo.password, + }, + }; } export async function createConnectionsAndInviteNewUserInAdminGroupOfFirstConnection( - app: INestApplication, + app: INestApplication, ): Promise { - const connectionsId = { - firstId: null, - secondId: null, - firstAdminGroupId: null, - }; - - const mockFactory = new MockFactory(); - const connectionAdminUserInfo = await registerUserAndReturnUserInfo(app); - const simpleUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( - connectionAdminUserInfo.token, - undefined, - app, - undefined, - ); - const connectionAdminUserToken = connectionAdminUserInfo.token; - const simpleUserToken = simpleUserRegisterInfo.token; - - const newConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); - const newConnection2 = mockFactory.generateConnectionToTestMySQLDBInDocker(); - const _newGroup1 = mockFactory.generateCreateGroupDto1(); - const firstTable = await createTestTable(newConnection); - const secondTable = await createTestTable(newConnection2); - - const _tablePermissions = { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: false, - }; - - const createFirstConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .set('Cookie', connectionAdminUserToken) - .send(newConnection) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - if (createFirstConnectionResponse.status >= 300) { - console.error('first connection creation error: ' + createFirstConnectionResponse.text); - } - const createFirstConnectionRO = JSON.parse(createFirstConnectionResponse.text); - connectionsId.firstId = createFirstConnectionRO.id; - const createSecondConnectionResponse = await request(app.getHttpServer()) - .post('/connection') - .set('Cookie', connectionAdminUserToken) - .send(newConnection2) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - - if (createSecondConnectionResponse.status >= 300) { - console.error('second connection creation error: ' + createSecondConnectionResponse.text); - } - const createSecondConnectionRO = JSON.parse(createSecondConnectionResponse.text); - connectionsId.secondId = createSecondConnectionRO.id; - const email = simpleUserRegisterInfo.email; - - const getGroupsInFirstConnection = await request(app.getHttpServer()) - .get(`/connection/groups/${createFirstConnectionRO.id}`) - .set('Cookie', connectionAdminUserToken) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - const groupId = JSON.parse(getGroupsInFirstConnection.text)[0].group.id; - - const addUserInGroupResponce = await request(app.getHttpServer()) - .put('/group/user') - .set('Cookie', connectionAdminUserToken) - .send({ groupId, email }) - .set('Content-Type', 'application/json') - .set('Accept', 'application/json'); - connectionsId.firstAdminGroupId = groupId; - - if (addUserInGroupResponce.status >= 300) { - console.error('user invitation error: ' + addUserInGroupResponce.text); - } - - return { - firstTableInfo: firstTable, - secondTableInfo: secondTable, - permissions: { - table: { - visibility: true, - readonly: false, - add: true, - delete: true, - edit: false, - }, - }, - connections: { - firstId: connectionsId.firstId, - secondId: connectionsId.secondId, - }, - groups: { - firstAdminGroupId: groupId, - secondAdminGroupId: null, - }, - users: { - adminUserToken: connectionAdminUserToken, - simpleUserToken: simpleUserToken, - simpleUserEmail: simpleUserRegisterInfo.email, - adminUserEmail: connectionAdminUserInfo.email, - adminUserPassword: connectionAdminUserInfo.password, - simpleUserPassword: simpleUserRegisterInfo.password, - }, - }; + const connectionsId = { + firstId: null, + secondId: null, + firstAdminGroupId: null, + }; + + const mockFactory = new MockFactory(); + const connectionAdminUserInfo = await registerUserAndReturnUserInfo(app); + const simpleUserRegisterInfo = await inviteUserInCompanyAndAcceptInvitation( + connectionAdminUserInfo.token, + undefined, + app, + undefined, + ); + const connectionAdminUserToken = connectionAdminUserInfo.token; + const simpleUserToken = simpleUserRegisterInfo.token; + + const newConnection = mockFactory.generateConnectionToTestPostgresDBInDocker(); + const newConnection2 = mockFactory.generateConnectionToTestMySQLDBInDocker(); + const _newGroup1 = mockFactory.generateCreateGroupDto1(); + const firstTable = await createTestTable(newConnection); + const secondTable = await createTestTable(newConnection2); + + const _tablePermissions = { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: false, + }; + + const createFirstConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .set('Cookie', connectionAdminUserToken) + .send(newConnection) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + if (createFirstConnectionResponse.status >= 300) { + console.error('first connection creation error: ' + createFirstConnectionResponse.text); + } + const createFirstConnectionRO = JSON.parse(createFirstConnectionResponse.text); + connectionsId.firstId = createFirstConnectionRO.id; + const createSecondConnectionResponse = await request(app.getHttpServer()) + .post('/connection') + .set('Cookie', connectionAdminUserToken) + .send(newConnection2) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + + if (createSecondConnectionResponse.status >= 300) { + console.error('second connection creation error: ' + createSecondConnectionResponse.text); + } + const createSecondConnectionRO = JSON.parse(createSecondConnectionResponse.text); + connectionsId.secondId = createSecondConnectionRO.id; + const email = simpleUserRegisterInfo.email; + + const getGroupsInFirstConnection = await request(app.getHttpServer()) + .get(`/connection/groups/${createFirstConnectionRO.id}`) + .set('Cookie', connectionAdminUserToken) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + const groupId = JSON.parse(getGroupsInFirstConnection.text)[0].group.id; + + const addUserInGroupResponce = await request(app.getHttpServer()) + .put('/group/user') + .set('Cookie', connectionAdminUserToken) + .send({ groupId, email }) + .set('Content-Type', 'application/json') + .set('Accept', 'application/json'); + connectionsId.firstAdminGroupId = groupId; + + if (addUserInGroupResponce.status >= 300) { + console.error('user invitation error: ' + addUserInGroupResponce.text); + } + + return { + firstTableInfo: firstTable, + secondTableInfo: secondTable, + permissions: { + table: { + visibility: true, + readonly: false, + add: true, + delete: true, + edit: false, + }, + }, + connections: { + firstId: connectionsId.firstId, + secondId: connectionsId.secondId, + }, + groups: { + firstAdminGroupId: groupId, + secondAdminGroupId: null, + }, + users: { + adminUserToken: connectionAdminUserToken, + simpleUserToken: simpleUserToken, + simpleUserEmail: simpleUserRegisterInfo.email, + adminUserEmail: connectionAdminUserInfo.email, + adminUserPassword: connectionAdminUserInfo.password, + simpleUserPassword: simpleUserRegisterInfo.password, + }, + }; } interface IUserDifferentTableOnlyPermissionsFooData { - firstTableInfo: CreatedTableInfo; - secondTableInfo: CreatedTableInfo; - permissions: { - table: { - visibility: boolean; - readonly: boolean; - add: boolean; - delete: boolean; - edit: boolean; - }; - }; - connections: { - firstId: string; - secondId: string; - }; - groups: { - firstAdminGroupId: string; - secondAdminGroupId: string; - createdGroupId?: string; - }; - users: { - adminUserToken: string; - simpleUserToken: string; - simpleUserEmail: string; - adminUserEmail: string; - adminUserPassword: string; - simpleUserPassword: string; - }; + firstTableInfo: CreatedTableInfo; + secondTableInfo: CreatedTableInfo; + permissions: { + table: { + visibility: boolean; + readonly: boolean; + add: boolean; + delete: boolean; + edit: boolean; + }; + }; + connections: { + firstId: string; + secondId: string; + }; + groups: { + firstAdminGroupId: string; + secondAdminGroupId: string; + createdGroupId?: string; + }; + users: { + adminUserToken: string; + simpleUserToken: string; + simpleUserEmail: string; + adminUserEmail: string; + adminUserPassword: string; + simpleUserPassword: string; + }; } diff --git a/backend/tsconfig.build.json b/backend/tsconfig.build.json index 64f86c6bd..4491981e0 100644 --- a/backend/tsconfig.build.json +++ b/backend/tsconfig.build.json @@ -1,4 +1,4 @@ { - "extends": "./tsconfig.json", - "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] + "extends": "./tsconfig.json", + "exclude": ["node_modules", "test", "dist", "**/*spec.ts"] } diff --git a/backend/tsconfig.json b/backend/tsconfig.json index 9d4878910..3c3d593ba 100644 --- a/backend/tsconfig.json +++ b/backend/tsconfig.json @@ -1,24 +1,24 @@ { - "compilerOptions": { - "module": "ESNext", - "declaration": true, - "removeComments": true, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "allowJs": true, - "esModuleInterop": true, - "target": "ESNext", - "sourceMap": true, - "outDir": "./dist", - "rootDir": "./", - "baseUrl": "./", - "incremental": true, - "moduleResolution": "node", - "skipLibCheck": true - }, - // "references": [ - // { "path": "../shared-code" }, - // ], - "include": ["src", "test"], - "exclude": ["node_modules", "dist", "../node_modules"] + "compilerOptions": { + "module": "ESNext", + "declaration": true, + "removeComments": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowJs": true, + "esModuleInterop": true, + "target": "ESNext", + "sourceMap": true, + "outDir": "./dist", + "rootDir": "./", + "baseUrl": "./", + "incremental": true, + "moduleResolution": "node", + "skipLibCheck": true + }, + // "references": [ + // { "path": "../shared-code" }, + // ], + "include": ["src", "test"], + "exclude": ["node_modules", "dist", "../node_modules"] } diff --git a/shared-code/src/caching/caching-constants.ts b/shared-code/src/caching/caching-constants.ts index ad5f0c324..6fe1ea954 100644 --- a/shared-code/src/caching/caching-constants.ts +++ b/shared-code/src/caching/caching-constants.ts @@ -3,79 +3,79 @@ import { Database } from 'ibm_db'; import { MongoClientDB } from '../data-access-layer/data-access-objects/data-access-object-mongodb.js'; import { Client } from 'cassandra-driver'; export const CACHING_CONSTANTS = { - DEFAULT_CONNECTION_CACHE_OPTIONS: { - max: 150, - ttl: 1000 * 60 * 60, - updateAgeOnGet: false, - updateAgeOnHas: false, - dispose: async (knex: Knex) => { - await knex.destroy(); - }, - }, + DEFAULT_CONNECTION_CACHE_OPTIONS: { + max: 150, + ttl: 1000 * 60 * 60, + updateAgeOnGet: false, + updateAgeOnHas: false, + dispose: async (knex: Knex) => { + await knex.destroy(); + }, + }, - DEFAULT_IMDB_DB2_CACHE_OPTIONS: { - max: 150, - ttl: 1000 * 60 * 60, - updateAgeOnGet: false, - updateAgeOnHas: false, - dispose: async (db: Database) => { - await db.close(); - }, - }, + DEFAULT_IMDB_DB2_CACHE_OPTIONS: { + max: 150, + ttl: 1000 * 60 * 60, + updateAgeOnGet: false, + updateAgeOnHas: false, + dispose: async (db: Database) => { + await db.close(); + }, + }, - DEFAULT_CASSANDRA_CLIENT_CACHE_OPTIONS: { - max: 150, - ttl: 1000 * 60 * 60, - updateAgeOnGet: false, - updateAgeOnHas: false, - dispose: async (client: Client) => { - try { - await client.shutdown(); - } catch (_e) { - return; - } - }, - }, + DEFAULT_CASSANDRA_CLIENT_CACHE_OPTIONS: { + max: 150, + ttl: 1000 * 60 * 60, + updateAgeOnGet: false, + updateAgeOnHas: false, + dispose: async (client: Client) => { + try { + await client.shutdown(); + } catch (_e) { + return; + } + }, + }, - DEFAULT_MONGO_DB_CACHE_OPTIONS: { - max: 150, - ttl: 1000 * 60 * 60, - updateAgeOnGet: false, - updateAgeOnHas: false, - dispose: async (connectionData: MongoClientDB) => { - await connectionData.dbClient.close(); - }, - }, + DEFAULT_MONGO_DB_CACHE_OPTIONS: { + max: 150, + ttl: 1000 * 60 * 60, + updateAgeOnGet: false, + updateAgeOnHas: false, + dispose: async (connectionData: MongoClientDB) => { + await connectionData.dbClient.close(); + }, + }, - DEFAULT_REDIS_CLIENT_CACHE_OPTIONS: { - max: 150, - ttl: 1000 * 60 * 60, - updateAgeOnGet: false, - updateAgeOnHas: false, - dispose: async (client: any) => { - try { - await client.quit(); - } catch (_e) { - return; - } - }, - }, + DEFAULT_REDIS_CLIENT_CACHE_OPTIONS: { + max: 150, + ttl: 1000 * 60 * 60, + updateAgeOnGet: false, + updateAgeOnHas: false, + dispose: async (client: any) => { + try { + await client.quit(); + } catch (_e) { + return; + } + }, + }, - DEFAULT_TUNNEL_CACHE_OPTIONS: { - max: 100, - ttl: 1000 * 60 * 60, - dispose: async (tnl: any) => { - try { - await tnl?.server?.close(); - await tnl?.client?.destroy(); - await tnl?.database?.close(); - } catch (e) { - console.error('Tunnel closing error: ' + e); - } - }, - }, - DEFAULT_TABLE_STRUCTURE_ELEMENTS_CACHE_OPTIONS: { - max: 150, - ttl: 1000 * 60, - }, + DEFAULT_TUNNEL_CACHE_OPTIONS: { + max: 100, + ttl: 1000 * 60 * 60, + dispose: async (tnl: any) => { + try { + await tnl?.server?.close(); + await tnl?.client?.destroy(); + await tnl?.database?.close(); + } catch (e) { + console.error('Tunnel closing error: ' + e); + } + }, + }, + DEFAULT_TABLE_STRUCTURE_ELEMENTS_CACHE_OPTIONS: { + max: 150, + ttl: 1000 * 60, + }, }; diff --git a/shared-code/src/caching/lru-storage.ts b/shared-code/src/caching/lru-storage.ts index eb4fa8701..ed86698cb 100644 --- a/shared-code/src/caching/lru-storage.ts +++ b/shared-code/src/caching/lru-storage.ts @@ -4,8 +4,8 @@ import { Knex } from 'knex'; import { LRUCache } from 'lru-cache'; import { MongoClientDB } from '../data-access-layer/data-access-objects/data-access-object-mongodb.js'; import { - ConnectionAgentParams, - ConnectionParams, + ConnectionAgentParams, + ConnectionParams, } from '../data-access-layer/shared/data-structures/connections-params.ds.js'; import { ForeignKeyDS } from '../data-access-layer/shared/data-structures/foreign-key.ds.js'; import { PrimaryKeyDS } from '../data-access-layer/shared/data-structures/primary-key.ds.js'; @@ -21,208 +21,208 @@ const tableForeignKeysCache = new LRUCache(CACHING_CONSTANTS.DEFAULT_TABLE_STRUC const tablePrimaryKeysCache = new LRUCache(CACHING_CONSTANTS.DEFAULT_TABLE_STRUCTURE_ELEMENTS_CACHE_OPTIONS); const redisClientCache = new LRUCache(CACHING_CONSTANTS.DEFAULT_REDIS_CLIENT_CACHE_OPTIONS); export class LRUStorage { - public static getRedisClientCache(connection: ConnectionParams): any | null { - const cachedClient = redisClientCache.get(LRUStorage.getConnectionIdentifier(connection)); - return cachedClient ? cachedClient : null; - } - - public static setRedisClientCache(connection: ConnectionParams, client: any): void { - redisClientCache.set(LRUStorage.getConnectionIdentifier(connection), client); - } - - public static delRedisClientCache(connection: ConnectionParams): void { - redisClientCache.delete(LRUStorage.getConnectionIdentifier(connection)); - } - - public static setCassandraClientCache(connection: ConnectionParams, client: Client): void { - cassandraClientCache.set(LRUStorage.getConnectionIdentifier(connection), client); - } - - public static getCassandraClientCache(connection: ConnectionParams): Client | null { - const cachedClient = cassandraClientCache.get(LRUStorage.getConnectionIdentifier(connection)) as Client; - return cachedClient ? cachedClient : null; - } - - public static delCassandraClientCache(connection: ConnectionParams): void { - cassandraClientCache.delete(LRUStorage.getConnectionIdentifier(connection)); - } - - public static getCassandraClientCount(): number { - return cassandraClientCache.size; - } - - public static clearCassandraClientCache(): void { - cassandraClientCache.clear(); - } - - public static setMongoDbCache(connection: ConnectionParams, newDb: MongoClientDB): void { - mongoDbCache.set(LRUStorage.getConnectionIdentifier(connection), newDb); - } - - public static getMongoDbCache(connection: ConnectionParams): MongoClientDB | null { - const cachedDb = mongoDbCache.get(LRUStorage.getConnectionIdentifier(connection)) as MongoClientDB; - return cachedDb ? cachedDb : null; - } - - public static delMongoDbCache(connection: ConnectionParams): void { - mongoDbCache.delete(LRUStorage.getConnectionIdentifier(connection)); - } - - public static getImdbDb2Cache(connection: ConnectionParams): Database | null { - const cachedDb = imdbDb2Cache.get(LRUStorage.getConnectionIdentifier(connection)) as Database; - return cachedDb ? cachedDb : null; - } - - public static delImdbDb2Cache(connection: ConnectionParams): void { - imdbDb2Cache.delete(LRUStorage.getConnectionIdentifier(connection)); - } - - public static setImdbDb2Cache(connection: ConnectionParams, newDb: Database): void { - imdbDb2Cache.set(LRUStorage.getConnectionIdentifier(connection), newDb); - } - - public static getCachedKnex(connectionConfig: ConnectionParams): Knex | null { - const cachedKnex = knexCache.get(LRUStorage.getConnectionIdentifier(connectionConfig)) as Knex; - return cachedKnex ? cachedKnex : null; - } - - public static setKnexCache(connectionConfig: ConnectionParams, newKnex: Knex): void { - knexCache.set(LRUStorage.getConnectionIdentifier(connectionConfig), newKnex); - } - - public static delKnexCache(connectionConfig: ConnectionParams): void { - knexCache.delete(LRUStorage.getConnectionIdentifier(connectionConfig)); - } - - public static getTunnelCache(connection: ConnectionParams): any { - const cachedTnl = tunnelCache.get(LRUStorage.getConnectionIdentifier(connection)); - return cachedTnl ? cachedTnl : null; - } - - public static setTunnelCache(connection: ConnectionParams, tnlObj: Record): void { - tunnelCache.set(LRUStorage.getConnectionIdentifier(connection), tnlObj); - } - - public static delTunnelCache(connection: ConnectionParams): void { - tunnelCache.delete(LRUStorage.getConnectionIdentifier(connection)); - } - - public static setTableForeignKeysCache( - connection: ConnectionParams | ConnectionAgentParams, - tableName: string, - foreignKeys: Array, - ): void { - const connectionCopy = { - ...connection, - }; - const cacheObj = JSON.stringify({ connectionCopy, tableName }); - tableForeignKeysCache.set(cacheObj, foreignKeys); - } - - public static getTableForeignKeysCache( - connection: ConnectionParams | ConnectionAgentParams, - tableName: string, - ): Array { - const connectionCopy = { - ...connection, - }; - const cacheObj = JSON.stringify({ connectionCopy, tableName }); - const foundKeys = tableForeignKeysCache.get(cacheObj) as Array; - return foundKeys ? foundKeys : null; - } - - public static setTablePrimaryKeysCache( - connection: ConnectionParams | ConnectionAgentParams, - tableName: string, - primaryKeys: Array, - ): void { - const connectionCopy = { - ...connection, - }; - const cacheObj = JSON.stringify({ connectionCopy, tableName }); - tablePrimaryKeysCache.set(cacheObj, primaryKeys); - } - - public static getTablePrimaryKeysCache( - connection: ConnectionParams | ConnectionAgentParams, - tableName: string, - ): Array { - const connectionCopy = { - ...connection, - }; - const cacheObj = JSON.stringify({ connectionCopy, tableName }); - const foundKeys = tablePrimaryKeysCache.get(cacheObj) as Array; - return foundKeys ? foundKeys : null; - } - - public static getTableStructureCache( - connection: ConnectionParams | ConnectionAgentParams, - tableName: string, - ): Array { - const connectionCopy = { - ...connection, - }; - const cacheObj = JSON.stringify({ connectionCopy, tableName }); - const foundStructure = tableStructureCache.get(cacheObj) as Array; - return foundStructure ? foundStructure : null; - } - - public static setTableStructureCache( - connection: ConnectionParams | ConnectionAgentParams, - tableName: string, - structure: Array, - ): void { - const connectionCopy = { - ...connection, - }; - const cacheObj = JSON.stringify({ connectionCopy, tableName }); - tableStructureCache.set(cacheObj, structure); - } - - public static getConnectionIdentifier(connectionParams: ConnectionParams | ConnectionAgentParams): string { - if (LRUStorage.isConnectionAgentParams(connectionParams)) { - const cacheObj = { - id: connectionParams.id, - token: connectionParams.token, - signing_key: connectionParams.signing_key, - }; - return JSON.stringify(cacheObj); - } - if (connectionParams.isTestConnection) { - return connectionParams.host; - } - if (connectionParams.ssh) { - const cacheObj = { - id: connectionParams.id, - signing_key: connectionParams.signing_key, - type: connectionParams.type, - username: connectionParams.username, - database: connectionParams.database, - }; - return JSON.stringify(cacheObj); - } - const cacheObj = { - // id: connectionParams.id, - // signing_key: connectionParams.signing_key, - host: connectionParams.host, - port: connectionParams.port, - username: connectionParams.username, - database: connectionParams.database, - type: connectionParams.type, - schema: connectionParams.schema ? connectionParams.schema : null, - authSource: connectionParams.authSource ? connectionParams.authSource : null, - sid: connectionParams.sid ? connectionParams.sid : null, - dataCenter: connectionParams.dataCenter ? connectionParams.dataCenter : null, - }; - return JSON.stringify(cacheObj); - } - - public static isConnectionAgentParams( - connectionParams: ConnectionParams | ConnectionAgentParams, - ): connectionParams is ConnectionAgentParams { - if (Object.hasOwn(connectionParams, 'token') && (connectionParams as ConnectionAgentParams).token) { - return true; - } - return false; - } + public static getRedisClientCache(connection: ConnectionParams): any | null { + const cachedClient = redisClientCache.get(LRUStorage.getConnectionIdentifier(connection)); + return cachedClient ? cachedClient : null; + } + + public static setRedisClientCache(connection: ConnectionParams, client: any): void { + redisClientCache.set(LRUStorage.getConnectionIdentifier(connection), client); + } + + public static delRedisClientCache(connection: ConnectionParams): void { + redisClientCache.delete(LRUStorage.getConnectionIdentifier(connection)); + } + + public static setCassandraClientCache(connection: ConnectionParams, client: Client): void { + cassandraClientCache.set(LRUStorage.getConnectionIdentifier(connection), client); + } + + public static getCassandraClientCache(connection: ConnectionParams): Client | null { + const cachedClient = cassandraClientCache.get(LRUStorage.getConnectionIdentifier(connection)) as Client; + return cachedClient ? cachedClient : null; + } + + public static delCassandraClientCache(connection: ConnectionParams): void { + cassandraClientCache.delete(LRUStorage.getConnectionIdentifier(connection)); + } + + public static getCassandraClientCount(): number { + return cassandraClientCache.size; + } + + public static clearCassandraClientCache(): void { + cassandraClientCache.clear(); + } + + public static setMongoDbCache(connection: ConnectionParams, newDb: MongoClientDB): void { + mongoDbCache.set(LRUStorage.getConnectionIdentifier(connection), newDb); + } + + public static getMongoDbCache(connection: ConnectionParams): MongoClientDB | null { + const cachedDb = mongoDbCache.get(LRUStorage.getConnectionIdentifier(connection)) as MongoClientDB; + return cachedDb ? cachedDb : null; + } + + public static delMongoDbCache(connection: ConnectionParams): void { + mongoDbCache.delete(LRUStorage.getConnectionIdentifier(connection)); + } + + public static getImdbDb2Cache(connection: ConnectionParams): Database | null { + const cachedDb = imdbDb2Cache.get(LRUStorage.getConnectionIdentifier(connection)) as Database; + return cachedDb ? cachedDb : null; + } + + public static delImdbDb2Cache(connection: ConnectionParams): void { + imdbDb2Cache.delete(LRUStorage.getConnectionIdentifier(connection)); + } + + public static setImdbDb2Cache(connection: ConnectionParams, newDb: Database): void { + imdbDb2Cache.set(LRUStorage.getConnectionIdentifier(connection), newDb); + } + + public static getCachedKnex(connectionConfig: ConnectionParams): Knex | null { + const cachedKnex = knexCache.get(LRUStorage.getConnectionIdentifier(connectionConfig)) as Knex; + return cachedKnex ? cachedKnex : null; + } + + public static setKnexCache(connectionConfig: ConnectionParams, newKnex: Knex): void { + knexCache.set(LRUStorage.getConnectionIdentifier(connectionConfig), newKnex); + } + + public static delKnexCache(connectionConfig: ConnectionParams): void { + knexCache.delete(LRUStorage.getConnectionIdentifier(connectionConfig)); + } + + public static getTunnelCache(connection: ConnectionParams): any { + const cachedTnl = tunnelCache.get(LRUStorage.getConnectionIdentifier(connection)); + return cachedTnl ? cachedTnl : null; + } + + public static setTunnelCache(connection: ConnectionParams, tnlObj: Record): void { + tunnelCache.set(LRUStorage.getConnectionIdentifier(connection), tnlObj); + } + + public static delTunnelCache(connection: ConnectionParams): void { + tunnelCache.delete(LRUStorage.getConnectionIdentifier(connection)); + } + + public static setTableForeignKeysCache( + connection: ConnectionParams | ConnectionAgentParams, + tableName: string, + foreignKeys: Array, + ): void { + const connectionCopy = { + ...connection, + }; + const cacheObj = JSON.stringify({ connectionCopy, tableName }); + tableForeignKeysCache.set(cacheObj, foreignKeys); + } + + public static getTableForeignKeysCache( + connection: ConnectionParams | ConnectionAgentParams, + tableName: string, + ): Array { + const connectionCopy = { + ...connection, + }; + const cacheObj = JSON.stringify({ connectionCopy, tableName }); + const foundKeys = tableForeignKeysCache.get(cacheObj) as Array; + return foundKeys ? foundKeys : null; + } + + public static setTablePrimaryKeysCache( + connection: ConnectionParams | ConnectionAgentParams, + tableName: string, + primaryKeys: Array, + ): void { + const connectionCopy = { + ...connection, + }; + const cacheObj = JSON.stringify({ connectionCopy, tableName }); + tablePrimaryKeysCache.set(cacheObj, primaryKeys); + } + + public static getTablePrimaryKeysCache( + connection: ConnectionParams | ConnectionAgentParams, + tableName: string, + ): Array { + const connectionCopy = { + ...connection, + }; + const cacheObj = JSON.stringify({ connectionCopy, tableName }); + const foundKeys = tablePrimaryKeysCache.get(cacheObj) as Array; + return foundKeys ? foundKeys : null; + } + + public static getTableStructureCache( + connection: ConnectionParams | ConnectionAgentParams, + tableName: string, + ): Array { + const connectionCopy = { + ...connection, + }; + const cacheObj = JSON.stringify({ connectionCopy, tableName }); + const foundStructure = tableStructureCache.get(cacheObj) as Array; + return foundStructure ? foundStructure : null; + } + + public static setTableStructureCache( + connection: ConnectionParams | ConnectionAgentParams, + tableName: string, + structure: Array, + ): void { + const connectionCopy = { + ...connection, + }; + const cacheObj = JSON.stringify({ connectionCopy, tableName }); + tableStructureCache.set(cacheObj, structure); + } + + public static getConnectionIdentifier(connectionParams: ConnectionParams | ConnectionAgentParams): string { + if (LRUStorage.isConnectionAgentParams(connectionParams)) { + const cacheObj = { + id: connectionParams.id, + token: connectionParams.token, + signing_key: connectionParams.signing_key, + }; + return JSON.stringify(cacheObj); + } + if (connectionParams.isTestConnection) { + return connectionParams.host; + } + if (connectionParams.ssh) { + const cacheObj = { + id: connectionParams.id, + signing_key: connectionParams.signing_key, + type: connectionParams.type, + username: connectionParams.username, + database: connectionParams.database, + }; + return JSON.stringify(cacheObj); + } + const cacheObj = { + // id: connectionParams.id, + // signing_key: connectionParams.signing_key, + host: connectionParams.host, + port: connectionParams.port, + username: connectionParams.username, + database: connectionParams.database, + type: connectionParams.type, + schema: connectionParams.schema ? connectionParams.schema : null, + authSource: connectionParams.authSource ? connectionParams.authSource : null, + sid: connectionParams.sid ? connectionParams.sid : null, + dataCenter: connectionParams.dataCenter ? connectionParams.dataCenter : null, + }; + return JSON.stringify(cacheObj); + } + + public static isConnectionAgentParams( + connectionParams: ConnectionParams | ConnectionAgentParams, + ): connectionParams is ConnectionAgentParams { + if (Object.hasOwn(connectionParams, 'token') && (connectionParams as ConnectionAgentParams).token) { + return true; + } + return false; + } } diff --git a/shared-code/src/data-access-layer/data-access-objects/basic-data-access-object.ts b/shared-code/src/data-access-layer/data-access-objects/basic-data-access-object.ts index 8452018d8..deb4ab7f0 100644 --- a/shared-code/src/data-access-layer/data-access-objects/basic-data-access-object.ts +++ b/shared-code/src/data-access-layer/data-access-objects/basic-data-access-object.ts @@ -6,110 +6,110 @@ import { TableSettingsDS } from '../shared/data-structures/table-settings.ds.js' import { TableStructureDS } from '../shared/data-structures/table-structure.ds.js'; export class BasicDataAccessObject { - protected connection: ConnectionParams; + protected connection: ConnectionParams; - constructor(connection: ConnectionParams) { - this.connection = connection; - } - protected async configureKnex(): Promise> { - const knexManager = KnexManager.knexStorage(); - return knexManager.get(this.connection.type)(this.connection); - } + constructor(connection: ConnectionParams) { + this.connection = connection; + } + protected async configureKnex(): Promise> { + const knexManager = KnexManager.knexStorage(); + return knexManager.get(this.connection.type)(this.connection); + } - protected findAvailableFields(settings: TableSettingsDS, tableStructure: Array): Array { - let availableFields: Array = []; - const fieldsFromStructure = tableStructure.map((el) => { - return el.column_name; - }); + protected findAvailableFields(settings: TableSettingsDS, tableStructure: Array): Array { + let availableFields: Array = []; + const fieldsFromStructure = tableStructure.map((el) => { + return el.column_name; + }); - if (isObjectEmpty(settings)) { - availableFields = tableStructure.map((el) => { - return el.column_name; - }); - return availableFields; - } - const excludedFields = settings.excluded_fields; + if (isObjectEmpty(settings)) { + availableFields = tableStructure.map((el) => { + return el.column_name; + }); + return availableFields; + } + const excludedFields = settings.excluded_fields; - if (settings.list_fields && settings.list_fields.length > 0) { - const validListFields = settings.list_fields.filter((fieldName) => { - return fieldsFromStructure.includes(fieldName); - }); + if (settings.list_fields && settings.list_fields.length > 0) { + const validListFields = settings.list_fields.filter((fieldName) => { + return fieldsFromStructure.includes(fieldName); + }); - const additionalFields = fieldsFromStructure.filter((fieldName) => { - return !settings.list_fields.includes(fieldName); - }); + const additionalFields = fieldsFromStructure.filter((fieldName) => { + return !settings.list_fields.includes(fieldName); + }); - availableFields = [...validListFields, ...additionalFields]; - } else { - availableFields = tableStructure.map((el) => { - return el.column_name; - }); - } - if (excludedFields && excludedFields.length > 0) { - for (const field of excludedFields) { - const delIndex = availableFields.indexOf(field); - if (delIndex >= 0) { - availableFields.splice(availableFields.indexOf(field), 1); - } - } - } - return availableFields; - } + availableFields = [...validListFields, ...additionalFields]; + } else { + availableFields = tableStructure.map((el) => { + return el.column_name; + }); + } + if (excludedFields && excludedFields.length > 0) { + for (const field of excludedFields) { + const delIndex = availableFields.indexOf(field); + if (delIndex >= 0) { + availableFields.splice(availableFields.indexOf(field), 1); + } + } + } + return availableFields; + } - protected validateNamesAndThrowError(names: string | Array): void { - if (typeof names === 'string') { - if (!this.isValidName(names)) { - throw new Error(`Parameter "${names}" is invalid`); - } - } - if (Array.isArray(names)) { - for (const name of names) { - if (!this.isValidName(name)) { - throw new Error(`Parameter "${name}" is invalid`); - } - } - } - } + protected validateNamesAndThrowError(names: string | Array): void { + if (typeof names === 'string') { + if (!this.isValidName(names)) { + throw new Error(`Parameter "${names}" is invalid`); + } + } + if (Array.isArray(names)) { + for (const name of names) { + if (!this.isValidName(name)) { + throw new Error(`Parameter "${name}" is invalid`); + } + } + } + } - protected isDateTimeType(columnTypeName: string): boolean { - const dateTimeDataTypes = [ - // PostgreSQL - 'DATE', - 'TIME', - 'TIMETZ', - 'TIMESTAMP', - 'TIMESTAMPTZ', + protected isDateTimeType(columnTypeName: string): boolean { + const dateTimeDataTypes = [ + // PostgreSQL + 'DATE', + 'TIME', + 'TIMETZ', + 'TIMESTAMP', + 'TIMESTAMPTZ', - // MySQL - 'DATE', - 'DATETIME', - 'TIMESTAMP', - 'TIME', - 'YEAR', + // MySQL + 'DATE', + 'DATETIME', + 'TIMESTAMP', + 'TIME', + 'YEAR', - // MS SQL Server - 'DATE', - 'DATETIME', - 'DATETIME2', - 'DATETIMEOFFSET', - 'SMALLDATETIME', - 'TIME', + // MS SQL Server + 'DATE', + 'DATETIME', + 'DATETIME2', + 'DATETIMEOFFSET', + 'SMALLDATETIME', + 'TIME', - // OracleDB - 'DATE', - 'TIMESTAMP', - 'TIMESTAMP WITH TIME ZONE', - 'TIMESTAMP WITH LOCAL TIME ZONE', + // OracleDB + 'DATE', + 'TIMESTAMP', + 'TIMESTAMP WITH TIME ZONE', + 'TIMESTAMP WITH LOCAL TIME ZONE', - // IBM Db2 - 'DATE', - 'TIME', - 'TIMESTAMP', - ]; - return dateTimeDataTypes.includes(columnTypeName.toUpperCase()); - } + // IBM Db2 + 'DATE', + 'TIME', + 'TIMESTAMP', + ]; + return dateTimeDataTypes.includes(columnTypeName.toUpperCase()); + } - private isValidName(name: string): boolean { - return typeof name === 'string' && name.length > 0 && /^[a-zA-Z0-9_]+$/.test(name); - } + private isValidName(name: string): boolean { + return typeof name === 'string' && name.length > 0 && /^[a-zA-Z0-9_]+$/.test(name); + } } diff --git a/shared-code/src/data-access-layer/data-access-objects/data-access-object-cassandra.ts b/shared-code/src/data-access-layer/data-access-objects/data-access-object-cassandra.ts index 37669c846..84f9e1f6e 100644 --- a/shared-code/src/data-access-layer/data-access-objects/data-access-object-cassandra.ts +++ b/shared-code/src/data-access-layer/data-access-objects/data-access-object-cassandra.ts @@ -25,856 +25,855 @@ import { IDataAccessObject } from '../../shared/interfaces/data-access-object.in import { BasicDataAccessObject } from './basic-data-access-object.js'; export class DataAccessObjectCassandra extends BasicDataAccessObject implements IDataAccessObject { - - public async addRowInTable( - tableName: string, - row: Record, - ): Promise | number> { - try { - const client = await this.getCassandraClient(); - const columns = Object.keys(row).map((col) => col.toLowerCase()); - const values = Object.values(row); - const placeholders = columns.map(() => '?').join(', '); - const query = `INSERT INTO ${tableName.toLowerCase()} (${columns.join(', ')}) VALUES (${placeholders})`; - await client.execute(query, values, { prepare: true }); - return row; - } catch (error) { - throw new Error(`Failed to add row in table: ${error.message}`); - } - } - - public async deleteRowInTable( - tableName: string, - primaryKey: Record, - ): Promise> { - try { - const client = await this.getCassandraClient(); - const primaryKeys = await this.getTablePrimaryColumns(tableName); - const whereConditions = []; - const params = []; - for (const key of primaryKeys) { - const keyName = key.column_name; - if (primaryKey[keyName] !== undefined) { - whereConditions.push(`${keyName} = ?`); - params.push(primaryKey[keyName]); - } - } - if (whereConditions.length === 0) { - throw new Error('No primary key values provided for deletion'); - } - const deleteQuery = `DELETE FROM ${tableName.toLowerCase()} WHERE ${whereConditions.join(' AND ')}`; - await client.execute(deleteQuery, params, { prepare: true }); - return primaryKey; - } catch (error) { - throw new Error(`Failed to delete row in table: ${error.message}`); - } - } - - public async getIdentityColumns( - tableName: string, - referencedFieldName: string, - identityColumnName: string, - fieldValues: Array, - ): Promise>> { - try { - const client = await this.getCassandraClient(); - const results = []; - for (const value of fieldValues) { - const query = `SELECT ${identityColumnName.toLowerCase()} FROM ${tableName.toLowerCase()} WHERE ${referencedFieldName.toLowerCase()} = ? ALLOW FILTERING`; - const result = await client.execute(query, [value], { prepare: true }); - for (const row of result.rows) { - results.push(row); - } - } - return results; - } catch (error) { - throw new Error(`Failed to get identity columns: ${error.message}`); - } - } - - public async getRowByPrimaryKey( - tableName: string, - primaryKey: Record, - settings: TableSettingsDS, - ): Promise> { - try { - const client = await this.getCassandraClient(); - let availableFields: string[] = []; - if (settings) { - const tableStructure = await this.getTableStructure(tableName); - availableFields = this.findAvailableFields(settings, tableStructure); - } - const primaryKeys = await this.getTablePrimaryColumns(tableName); - - const whereConditions = []; - const params = []; - for (const key of primaryKeys) { - const keyName = key.column_name; - if (primaryKey[keyName] !== undefined) { - whereConditions.push(`${keyName} = ?`); - params.push(primaryKey[keyName]); - } - } - if (whereConditions.length === 0) { - throw new Error('No primary key values provided'); - } - const fieldsToSelect = availableFields.length ? availableFields.join(', ') : '*'; - const query = `SELECT ${fieldsToSelect} FROM ${tableName.toLowerCase()} WHERE ${whereConditions.join(' AND ')}`; - const result = await client.execute(query, params, { prepare: true }); - return result.rows[0]; - } catch (error) { - throw new Error(`Failed to get row by primary key: ${error.message}`); - } - } - - public async bulkGetRowsFromTableByPrimaryKeys( - tableName: string, - primaryKeys: Array>, - settings: TableSettingsDS, - ): Promise>> { - try { - const client = await this.getCassandraClient(); - let availableFields: string[] = []; - if (settings) { - const tableStructure = await this.getTableStructure(tableName); - availableFields = this.findAvailableFields(settings, tableStructure); - } - const tablePrimaryKeys = await this.getTablePrimaryColumns(tableName); - const results = []; - for (const primaryKey of primaryKeys) { - const whereConditions = []; - const params = []; - for (const key of tablePrimaryKeys) { - const keyName = key.column_name; - if (primaryKey[keyName] !== undefined) { - whereConditions.push(`${keyName} = ?`); - params.push(primaryKey[keyName]); - } - } - if (whereConditions.length === 0) { - continue; - } - const fieldsToSelect = availableFields.length ? availableFields.join(', ') : '*'; - const query = `SELECT ${fieldsToSelect} FROM ${tableName.toLowerCase()} WHERE ${whereConditions.join(' AND ')}`; - const result = await client.execute(query, params, { prepare: true }); - for (const row of result.rows) { - results.push(row); - } - } - return results; - } catch (error) { - throw new Error(`Failed to bulk get rows from table by primary keys: ${error.message}`); - } - } - - public async getRowsFromTable( - tableName: string, - settings: TableSettingsDS, - page: number, - perPage: number, - searchedFieldValue: string, - filteringFields: Array, - autocompleteFields: AutocompleteFieldsDS, - tableStructure: TableStructureDS[] | null, - ): Promise { - page = page > 0 ? page : DAO_CONSTANTS.DEFAULT_PAGINATION.page; - perPage = - perPage > 0 - ? perPage - : settings.list_per_page > 0 - ? settings.list_per_page - : DAO_CONSTANTS.DEFAULT_PAGINATION.perPage; - try { - const client = await this.getCassandraClient(); - if (!tableStructure) { - tableStructure = await this.getTableStructure(tableName); - } - const availableFields = this.findAvailableFields(settings, tableStructure); - - if (autocompleteFields?.value && autocompleteFields?.fields?.length > 0) { - const { fields, value } = autocompleteFields; - const selectFields = fields.length > 0 ? fields.map((f) => f.toLowerCase()).join(', ') : '*'; - const allRows: any[] = []; - const seen = new Set(); - for (const field of fields) { - const query = `SELECT ${selectFields} FROM ${tableName.toLowerCase()} WHERE ${field.toLowerCase()} = ? ALLOW FILTERING LIMIT ${DAO_CONSTANTS.AUTOCOMPLETE_ROW_LIMIT}`; - const result = await client.execute(query, [value], { prepare: true }); - for (const row of result.rows) { - const key = JSON.stringify(row); - if (!seen.has(key)) { - seen.add(key); - allRows.push(row); - } - } - } - return { - data: allRows, - pagination: { - total: allRows.length, - lastPage: 1, - perPage: allRows.length, - currentPage: 1, - }, - large_dataset: allRows.length > DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT, - }; - } - - const whereConditions: string[] = []; - const params: any[] = []; - - let { search_fields } = settings; - if ((!search_fields || search_fields.length === 0) && searchedFieldValue) { - search_fields = availableFields; - } - - if (searchedFieldValue && search_fields?.length > 0) { - for (const field of search_fields) { - const fieldDef = tableStructure.find((col) => col.column_name === field); - if (!fieldDef) continue; - const type = fieldDef.data_type; - let valid = false; - let param; - if (type === 'uuid' && isUuid(searchedFieldValue)) { - valid = true; - param = searchedFieldValue; - } else if ((type === 'int' || type === 'bigint') && !Number.isNaN(Number(searchedFieldValue))) { - valid = true; - param = Number(searchedFieldValue); - } else if (type === 'date') { - if (typeof searchedFieldValue === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(searchedFieldValue)) { - valid = true; - param = searchedFieldValue; - } - } else if (type !== 'uuid' && type !== 'int' && type !== 'bigint') { - valid = true; - param = searchedFieldValue; - } - if (valid) { - whereConditions.push(`${field.toLowerCase()} = ?`); - params.push(param); - break; - } - } - } - - if (filteringFields?.length) { - for (const filter of filteringFields) { - if (filter.value !== undefined && filter.value !== null) { - switch (filter.criteria) { - case FilterCriteriaEnum.eq: - whereConditions.push(`${filter.field.toLowerCase()} = ?`); - params.push(filter.value); - break; - case FilterCriteriaEnum.gt: - whereConditions.push(`${filter.field.toLowerCase()} > ?`); - params.push(filter.value); - break; - case FilterCriteriaEnum.lt: - whereConditions.push(`${filter.field.toLowerCase()} < ?`); - params.push(filter.value); - break; - case FilterCriteriaEnum.gte: - whereConditions.push(`${filter.field.toLowerCase()} >= ?`); - params.push(filter.value); - break; - case FilterCriteriaEnum.lte: - whereConditions.push(`${filter.field.toLowerCase()} <= ?`); - params.push(filter.value); - break; - default: - break; - } - } - } - } - - const selectFields = availableFields.length > 0 ? availableFields.map((f) => f.toLowerCase()).join(', ') : '*'; - let query = `SELECT ${selectFields} FROM ${tableName.toLowerCase()}`; - if (whereConditions.length > 0) { - query += ` WHERE ${whereConditions.join(' AND ')} ALLOW FILTERING`; - } - - const { - totalCount, - isEstimated, - result: preExecutedResult, - } = await this.getRowCountWithFallback(client, tableName, whereConditions, params, query); - - let result: cassandra.types.ResultSet; - if (preExecutedResult) { - result = preExecutedResult; - } else { - result = await client.execute(query, params, { prepare: true }); - } - const startIndex = (page - 1) * perPage; - - const allRows = [...result.rows]; - if (settings?.ordering_field && settings?.ordering) { - const orderingField = settings.ordering_field.toLowerCase(); - const direction = settings.ordering === QueryOrderingEnum.DESC ? -1 : 1; - - allRows.sort((a, b) => { - const valueA = a[orderingField]; - const valueB = b[orderingField]; - if (valueA === null || valueA === undefined) return direction * -1; - if (valueB === null || valueB === undefined) return direction; - if (typeof valueA === 'number' && typeof valueB === 'number') { - return (valueA - valueB) * direction; - } else if (valueA instanceof Date && valueB instanceof Date) { - return (valueA.getTime() - valueB.getTime()) * direction; - } else { - return String(valueA).localeCompare(String(valueB)) * direction; - } - }); - } - - const rows = allRows.slice(startIndex, startIndex + perPage); - - const pagination = { - total: totalCount, - lastPage: Math.ceil(totalCount / perPage), - perPage, - currentPage: page, - }; - - return { - data: rows, - pagination, - large_dataset: totalCount > DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT || isEstimated, - }; - } catch (error) { - throw new Error(`Failed to get rows from table: ${error.message}`); - } - } - - public async getTableForeignKeys(_tableName: string): Promise> { - return []; - } - private cassandraTypeToReadable(type: any): string { - if (typeof type === 'string') { - return this.stripGenerics(type); - } - - if (type && typeof type === 'object') { - if (type.info?.name) { - return this.stripGenerics(type.info.name); - } - - if (type.code !== undefined) { - switch (type.code) { - case 0: - return 'custom'; - case 1: - return 'ascii'; - case 2: - return 'bigint'; - case 3: - return 'blob'; - case 4: - return 'boolean'; - case 5: - return 'counter'; - case 6: - return 'decimal'; - case 7: - return 'double'; - case 8: - return 'float'; - case 9: - return 'int'; - case 10: - return 'text'; - case 11: - return 'timestamp'; - case 12: - return 'uuid'; - case 13: - return 'varchar'; - case 14: - return 'varint'; - case 15: - return 'timeuuid'; - case 16: - return 'inet'; - case 17: - return 'date'; - case 18: - return 'time'; - case 19: - return 'smallint'; - case 20: - return 'tinyint'; - case 21: - return 'duration'; - case 32: - return 'list'; - case 33: - return 'map'; - case 34: - return 'set'; - case 48: - return 'udt'; - case 49: - return 'tuple'; - default: - return `type_code_${type.code}`; - } - } - } - return 'unknown'; - } - - private stripGenerics(typeName: string): string { - if (typeName.includes('<')) { - return typeName.substring(0, typeName.indexOf('<')); - } - return typeName; - } - - public async getTablePrimaryColumns(tableName: string): Promise> { - try { - const client = await this.getCassandraClient(); - const keyspaceMetadata = client.metadata.keyspaces[this.connection.database]; - if (!keyspaceMetadata) { - throw new Error(`Keyspace ${this.connection.database} not found`); - } - const tableMetadata = await client.metadata.getTable(this.connection.database, tableName.toLowerCase()); - if (!tableMetadata) { - throw new Error(`Table ${tableName} not found`); - } - const primaryKeys: Array = []; - tableMetadata.partitionKeys.forEach((column) => { - primaryKeys.push({ - column_name: column.name, - data_type: this.cassandraTypeToReadable(column.type), - }); - }); - tableMetadata.clusteringKeys.forEach((column) => { - primaryKeys.push({ - column_name: column.name, - data_type: this.cassandraTypeToReadable(column.type), - }); - }); - return primaryKeys; - } catch (error) { - throw new Error(`Failed to get table primary columns: ${error.message}`); - } - } - - public async getTablesFromDB(): Promise> { - try { - const client = await this.getCassandraClient(); - const keyspace = this.connection.database; - const tables: Array = []; - const tablesResult = await client.execute( - 'SELECT table_name FROM system_schema.tables WHERE keyspace_name = ?', - [keyspace], - { prepare: true }, - ); - for (const row of tablesResult.rows) { - tables.push({ - tableName: row.table_name, - isView: false, - }); - } - const viewsResult = await client.execute( - 'SELECT view_name FROM system_schema.views WHERE keyspace_name = ?', - [keyspace], - { prepare: true }, - ); - for (const row of viewsResult.rows) { - tables.push({ - tableName: row.view_name, - isView: true, - }); - } - return tables; - } catch (error) { - throw new Error(`Failed to get tables from database: ${error.message}`); - } - } - - public async getTableStructure(tableName: string): Promise> { - try { - const client = await this.getCassandraClient(); - const tableStructure: Array = []; - const keyspace = this.connection.database; - const tableNameLower = tableName.toLowerCase(); - const columnsResult = await client.execute( - 'SELECT column_name, type, kind FROM system_schema.columns WHERE keyspace_name = ? AND table_name = ?', - [keyspace, tableNameLower], - { prepare: true }, - ); - for (const row of columnsResult.rows) { - tableStructure.push({ - column_name: row.column_name, - column_default: null, - data_type: this.cassandraTypeToReadable(row.type), - allow_null: true, - character_maximum_length: null, - data_type_params: null, - udt_name: null, - }); - } - if (tableStructure.length === 0) { - throw new Error(`Table or view ${tableName} not found`); - } - return tableStructure; - } catch (error) { - throw new Error(`Failed to get table structure: ${error.message}`); - } - } - - public async testConnect(): Promise { - try { - const client = await this.getCassandraClient(); - await client.execute('SELECT key FROM system.local'); - return { - result: true, - message: 'Successfully connected', - }; - } catch (error) { - return { - result: false, - message: `Connection failed: ${error.message}`, - }; - } - } - - public async updateRowInTable( - tableName: string, - row: Record, - primaryKey: Record, - ): Promise> { - try { - const client = await this.getCassandraClient(); - const primaryKeys = await this.getTablePrimaryColumns(tableName); - const setClause = []; - const setParams = []; - for (const [key, value] of Object.entries(row)) { - if (!primaryKeys.some((pk) => pk.column_name === key)) { - setClause.push(`${key} = ?`); - setParams.push(value); - } - } - if (setClause.length === 0) { - throw new Error('No fields to update'); - } - const whereConditions = []; - const whereParams = []; - for (const key of primaryKeys) { - const keyName = key.column_name; - if (primaryKey[keyName] !== undefined) { - whereConditions.push(`${keyName} = ?`); - whereParams.push(primaryKey[keyName]); - } - } - if (whereConditions.length === 0) { - throw new Error('No primary key values provided for update'); - } - const query = `UPDATE ${tableName} SET ${setClause.join(', ')} WHERE ${whereConditions.join(' AND ')}`; - await client.execute(query, [...setParams, ...whereParams], { prepare: true }); - return primaryKey; - } catch (error) { - throw new Error(`Failed to update row in table: ${error.message}`); - } - } - - public async bulkUpdateRowsInTable( - tableName: string, - newValues: Record, - primaryKeys: Array>, - ): Promise>> { - try { - for (const primaryKey of primaryKeys) { - await this.updateRowInTable(tableName, newValues, primaryKey); - } - return primaryKeys; - } catch (error) { - throw new Error(`Failed to bulk update rows in table: ${error.message}`); - } - } - - public async bulkDeleteRowsInTable(tableName: string, primaryKeys: Array>): Promise { - try { - let deletedCount = 0; - for (const primaryKey of primaryKeys) { - try { - await this.deleteRowInTable(tableName, primaryKey); - deletedCount++; - } catch (error) { - console.error(`Error deleting row: ${error.message}`); - } - } - return deletedCount; - } catch (error) { - throw new Error(`Failed to bulk delete rows in table: ${error.message}`); - } - } - - public async validateSettings(settings: ValidateTableSettingsDS, tableName: string): Promise> { - try { - const [tableStructure, primaryColumns] = await Promise.all([ - this.getTableStructure(tableName), - this.getTablePrimaryColumns(tableName), - ]); - return tableSettingsFieldValidator(tableStructure, primaryColumns, settings); - } catch (error) { - throw new Error(`Failed to validate settings: ${error.message}`); - } - } - - public async getReferencedTableNamesAndColumns(_tableName: string): Promise> { - return []; - } - - public async isView(tableName: string): Promise { - try { - const client = await this.getCassandraClient(); - const keyspace = this.connection.database; - const result = await client.execute( - 'SELECT view_name FROM system_schema.views WHERE keyspace_name = ? AND view_name = ?', - [keyspace, tableName.toLowerCase()], - { prepare: true }, - ); - return result.rows.length > 0; - } catch (error) { - throw new Error(`Failed to check if table is a view: ${error.message}`); - } - } - - public async getTableRowsStream( - tableName: string, - settings: TableSettingsDS, - page: number, - perPage: number, - searchedFieldValue: string, - filteringFields: Array, - ): Promise> { - try { - const result = await this.getRowsFromTable( - tableName, - settings, - page, - perPage, - searchedFieldValue, - filteringFields, - null, - null, - ); - const readable = new Readable({ - objectMode: true, - read() { - for (const row of result.data) { - this.push(row); - } - this.push(null); - }, - }); - return readable; - } catch (error) { - throw new Error(`Failed to get table rows stream: ${error.message}`); - } - } - - public async importCSVInTable(file: Express.Multer.File, tableName: string): Promise { - try { - const tableStructure = await this.getTableStructure(tableName); - const bufferStream = new Readable(); - bufferStream.push(file.buffer); - bufferStream.push(null); - const parser = csv.parse({ columns: true, trim: true }); - const rows = []; - await new Promise((resolve, reject) => { - bufferStream - .pipe(parser) - .on('data', (row) => rows.push(row)) - .on('error', (err) => reject(err)) - .on('end', () => resolve()); - }); - for (const row of rows) { - const processedRow = {}; - for (const field of tableStructure) { - const columnName = field.column_name; - - if (row[columnName] !== undefined) { - let value = row[columnName]; - if (field.data_type === 'uuid' && typeof value === 'string') { - value = value.replace(/^"+|"+$/g, ''); - } else if ( - field.data_type.includes('int') || - field.data_type.includes('float') || - field.data_type.includes('double') - ) { - value = Number.isNaN(parseFloat(value)) ? null : parseFloat(value); - } else if (field.data_type === 'timestamp' && !Number.isNaN(Number(value))) { - const timestamp = Number(value); - value = new Date(timestamp); - } else if (field.data_type.includes('boolean')) { - value = value.toLowerCase() === 'true'; - } - processedRow[columnName] = value; - } - } - - await this.addRowInTable(tableName, processedRow); - } - } catch (error) { - throw new Error(`Failed to import CSV: ${error.message}`); - } - } - - public async executeRawQuery(query: string): Promise>> { - try { - const client = await this.getCassandraClient(); - const result = await client.execute(query, [], { prepare: true }); - return result.rows; - } catch (error) { - throw new Error(`Failed to execute raw query: ${error.message}`); - } - } - - private isAWSConnection(): boolean { - const { host } = this.connection; - - if (host.includes('cassandra') && host.includes('amazonaws.com')) { - return true; - } - - if (host.includes('amazonaws.com')) { - return true; - } - - const ec2HostRegex = /^(ec2-).*([.]compute[.]amazonaws[.]com)$/i; - if (ec2HostRegex.test(host)) { - return true; - } - - return false; - } - - private async getRowCountWithFallback( - client: cassandra.Client, - tableName: string, - whereConditions: string[], - params: any[], - query: string, - ): Promise<{ totalCount: number; isEstimated: boolean; result?: cassandra.types.ResultSet }> { - const isAWS = this.isAWSConnection(); - - if (isAWS) { - return this.estimateRowCount(client, tableName, whereConditions, params, query); - } - - try { - const countQuery = - `SELECT COUNT(*) as count FROM ${tableName.toLowerCase()}` + - (whereConditions.length > 0 ? ` WHERE ${whereConditions.join(' AND ')} ALLOW FILTERING` : ''); - const countResult = await client.execute(countQuery, params, { prepare: true }); - const totalCount = parseInt(countResult.rows[0].count?.toString() || '0', 10); - return { totalCount, isEstimated: false }; - } catch (countError) { - console.warn(`COUNT query failed, falling back to estimation: ${countError.message}`); - return this.estimateRowCount(client, tableName, whereConditions, params, query); - } - } - - private async estimateRowCount( - client: cassandra.Client, - tableName: string, - whereConditions: string[], - params: any[], - query: string, - ): Promise<{ totalCount: number; isEstimated: boolean; result: cassandra.types.ResultSet }> { - try { - const result = await client.execute(query, params, { prepare: true }); - let estimatedCount = result.rows.length; - if (whereConditions.length === 0) { - try { - const sampleQuery = `SELECT * FROM ${tableName.toLowerCase()} LIMIT 10000`; - const sampleResult = await client.execute(sampleQuery, [], { prepare: true }); - - if (sampleResult.rows.length >= 10000) { - estimatedCount = Math.max(estimatedCount, sampleResult.rows.length * 2); - } else { - estimatedCount = Math.max(estimatedCount, sampleResult.rows.length); - } - } catch (sampleError) { - console.warn(`Row count sampling failed: ${sampleError.message}`); - } - } - - return { totalCount: estimatedCount, isEstimated: true, result }; - } catch (error) { - console.warn(`Row count estimation failed: ${error.message}`); - return { totalCount: 100, isEstimated: true, result: null }; - } - } - - private async getCassandraClient(): Promise { - const cachedClient = LRUStorage.getCassandraClientCache(this.connection); - - if (cachedClient) { - try { - await cachedClient.execute('SELECT key FROM system.local LIMIT 1'); - return cachedClient as cassandra.Client; - } catch (error) { - console.log(`Cached client connection failed: ${error.message}. Creating new connection.`); - try { - await cachedClient.shutdown(); - } catch (_) { - } finally { - LRUStorage.delCassandraClientCache(this.connection); - } - } - } - try { - let contactPoints = [this.connection.host]; - let port = this.connection.port; - if (this.connection.ssh) { - if (!this.connection.sshHost || !this.connection.sshPort || !this.connection.sshUsername) { - throw new Error('SSH connection requires host, port, and username'); - } - const portForSSH = await getPort(); - const tunnelConnection: any = { - host: this.connection.host, - port: this.connection.port, - sshHost: this.connection.sshHost, - sshPort: this.connection.sshPort, - sshUsername: this.connection.sshUsername, - privateSSHKey: this.connection.privateSSHKey, - }; - await getTunnel(tunnelConnection, portForSSH); - contactPoints = ['127.0.0.1']; - port = portForSSH; - } - const authProvider = new cassandra.auth.PlainTextAuthProvider(this.connection.username, this.connection.password); - const clientOptions: cassandra.ClientOptions = { - contactPoints, - localDataCenter: this.connection.dataCenter || undefined, - keyspace: this.connection.database, - authProvider, - protocolOptions: { - port, - }, - queryOptions: { - consistency: cassandra.types.consistencies.localQuorum, - }, - }; - if (this.connection.ssl) { - clientOptions.sslOptions = { - rejectUnauthorized: false, - }; - if (this.connection.cert) { - clientOptions.sslOptions.ca = [this.connection.cert]; - } - } - const client = new cassandra.Client(clientOptions); - await client.connect(); - LRUStorage.setCassandraClientCache(this.connection, client); - return client; - } catch (error) { - throw new Error(`Failed to create Cassandra client: ${error.message}`); - } - } + public async addRowInTable( + tableName: string, + row: Record, + ): Promise | number> { + try { + const client = await this.getCassandraClient(); + const columns = Object.keys(row).map((col) => col.toLowerCase()); + const values = Object.values(row); + const placeholders = columns.map(() => '?').join(', '); + const query = `INSERT INTO ${tableName.toLowerCase()} (${columns.join(', ')}) VALUES (${placeholders})`; + await client.execute(query, values, { prepare: true }); + return row; + } catch (error) { + throw new Error(`Failed to add row in table: ${error.message}`); + } + } + + public async deleteRowInTable( + tableName: string, + primaryKey: Record, + ): Promise> { + try { + const client = await this.getCassandraClient(); + const primaryKeys = await this.getTablePrimaryColumns(tableName); + const whereConditions = []; + const params = []; + for (const key of primaryKeys) { + const keyName = key.column_name; + if (primaryKey[keyName] !== undefined) { + whereConditions.push(`${keyName} = ?`); + params.push(primaryKey[keyName]); + } + } + if (whereConditions.length === 0) { + throw new Error('No primary key values provided for deletion'); + } + const deleteQuery = `DELETE FROM ${tableName.toLowerCase()} WHERE ${whereConditions.join(' AND ')}`; + await client.execute(deleteQuery, params, { prepare: true }); + return primaryKey; + } catch (error) { + throw new Error(`Failed to delete row in table: ${error.message}`); + } + } + + public async getIdentityColumns( + tableName: string, + referencedFieldName: string, + identityColumnName: string, + fieldValues: Array, + ): Promise>> { + try { + const client = await this.getCassandraClient(); + const results = []; + for (const value of fieldValues) { + const query = `SELECT ${identityColumnName.toLowerCase()} FROM ${tableName.toLowerCase()} WHERE ${referencedFieldName.toLowerCase()} = ? ALLOW FILTERING`; + const result = await client.execute(query, [value], { prepare: true }); + for (const row of result.rows) { + results.push(row); + } + } + return results; + } catch (error) { + throw new Error(`Failed to get identity columns: ${error.message}`); + } + } + + public async getRowByPrimaryKey( + tableName: string, + primaryKey: Record, + settings: TableSettingsDS, + ): Promise> { + try { + const client = await this.getCassandraClient(); + let availableFields: string[] = []; + if (settings) { + const tableStructure = await this.getTableStructure(tableName); + availableFields = this.findAvailableFields(settings, tableStructure); + } + const primaryKeys = await this.getTablePrimaryColumns(tableName); + + const whereConditions = []; + const params = []; + for (const key of primaryKeys) { + const keyName = key.column_name; + if (primaryKey[keyName] !== undefined) { + whereConditions.push(`${keyName} = ?`); + params.push(primaryKey[keyName]); + } + } + if (whereConditions.length === 0) { + throw new Error('No primary key values provided'); + } + const fieldsToSelect = availableFields.length ? availableFields.join(', ') : '*'; + const query = `SELECT ${fieldsToSelect} FROM ${tableName.toLowerCase()} WHERE ${whereConditions.join(' AND ')}`; + const result = await client.execute(query, params, { prepare: true }); + return result.rows[0]; + } catch (error) { + throw new Error(`Failed to get row by primary key: ${error.message}`); + } + } + + public async bulkGetRowsFromTableByPrimaryKeys( + tableName: string, + primaryKeys: Array>, + settings: TableSettingsDS, + ): Promise>> { + try { + const client = await this.getCassandraClient(); + let availableFields: string[] = []; + if (settings) { + const tableStructure = await this.getTableStructure(tableName); + availableFields = this.findAvailableFields(settings, tableStructure); + } + const tablePrimaryKeys = await this.getTablePrimaryColumns(tableName); + const results = []; + for (const primaryKey of primaryKeys) { + const whereConditions = []; + const params = []; + for (const key of tablePrimaryKeys) { + const keyName = key.column_name; + if (primaryKey[keyName] !== undefined) { + whereConditions.push(`${keyName} = ?`); + params.push(primaryKey[keyName]); + } + } + if (whereConditions.length === 0) { + continue; + } + const fieldsToSelect = availableFields.length ? availableFields.join(', ') : '*'; + const query = `SELECT ${fieldsToSelect} FROM ${tableName.toLowerCase()} WHERE ${whereConditions.join(' AND ')}`; + const result = await client.execute(query, params, { prepare: true }); + for (const row of result.rows) { + results.push(row); + } + } + return results; + } catch (error) { + throw new Error(`Failed to bulk get rows from table by primary keys: ${error.message}`); + } + } + + public async getRowsFromTable( + tableName: string, + settings: TableSettingsDS, + page: number, + perPage: number, + searchedFieldValue: string, + filteringFields: Array, + autocompleteFields: AutocompleteFieldsDS, + tableStructure: TableStructureDS[] | null, + ): Promise { + page = page > 0 ? page : DAO_CONSTANTS.DEFAULT_PAGINATION.page; + perPage = + perPage > 0 + ? perPage + : settings.list_per_page > 0 + ? settings.list_per_page + : DAO_CONSTANTS.DEFAULT_PAGINATION.perPage; + try { + const client = await this.getCassandraClient(); + if (!tableStructure) { + tableStructure = await this.getTableStructure(tableName); + } + const availableFields = this.findAvailableFields(settings, tableStructure); + + if (autocompleteFields?.value && autocompleteFields?.fields?.length > 0) { + const { fields, value } = autocompleteFields; + const selectFields = fields.length > 0 ? fields.map((f) => f.toLowerCase()).join(', ') : '*'; + const allRows: any[] = []; + const seen = new Set(); + for (const field of fields) { + const query = `SELECT ${selectFields} FROM ${tableName.toLowerCase()} WHERE ${field.toLowerCase()} = ? ALLOW FILTERING LIMIT ${DAO_CONSTANTS.AUTOCOMPLETE_ROW_LIMIT}`; + const result = await client.execute(query, [value], { prepare: true }); + for (const row of result.rows) { + const key = JSON.stringify(row); + if (!seen.has(key)) { + seen.add(key); + allRows.push(row); + } + } + } + return { + data: allRows, + pagination: { + total: allRows.length, + lastPage: 1, + perPage: allRows.length, + currentPage: 1, + }, + large_dataset: allRows.length > DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT, + }; + } + + const whereConditions: string[] = []; + const params: any[] = []; + + let { search_fields } = settings; + if ((!search_fields || search_fields.length === 0) && searchedFieldValue) { + search_fields = availableFields; + } + + if (searchedFieldValue && search_fields?.length > 0) { + for (const field of search_fields) { + const fieldDef = tableStructure.find((col) => col.column_name === field); + if (!fieldDef) continue; + const type = fieldDef.data_type; + let valid = false; + let param; + if (type === 'uuid' && isUuid(searchedFieldValue)) { + valid = true; + param = searchedFieldValue; + } else if ((type === 'int' || type === 'bigint') && !Number.isNaN(Number(searchedFieldValue))) { + valid = true; + param = Number(searchedFieldValue); + } else if (type === 'date') { + if (typeof searchedFieldValue === 'string' && /^\d{4}-\d{2}-\d{2}$/.test(searchedFieldValue)) { + valid = true; + param = searchedFieldValue; + } + } else if (type !== 'uuid' && type !== 'int' && type !== 'bigint') { + valid = true; + param = searchedFieldValue; + } + if (valid) { + whereConditions.push(`${field.toLowerCase()} = ?`); + params.push(param); + break; + } + } + } + + if (filteringFields?.length) { + for (const filter of filteringFields) { + if (filter.value !== undefined && filter.value !== null) { + switch (filter.criteria) { + case FilterCriteriaEnum.eq: + whereConditions.push(`${filter.field.toLowerCase()} = ?`); + params.push(filter.value); + break; + case FilterCriteriaEnum.gt: + whereConditions.push(`${filter.field.toLowerCase()} > ?`); + params.push(filter.value); + break; + case FilterCriteriaEnum.lt: + whereConditions.push(`${filter.field.toLowerCase()} < ?`); + params.push(filter.value); + break; + case FilterCriteriaEnum.gte: + whereConditions.push(`${filter.field.toLowerCase()} >= ?`); + params.push(filter.value); + break; + case FilterCriteriaEnum.lte: + whereConditions.push(`${filter.field.toLowerCase()} <= ?`); + params.push(filter.value); + break; + default: + break; + } + } + } + } + + const selectFields = availableFields.length > 0 ? availableFields.map((f) => f.toLowerCase()).join(', ') : '*'; + let query = `SELECT ${selectFields} FROM ${tableName.toLowerCase()}`; + if (whereConditions.length > 0) { + query += ` WHERE ${whereConditions.join(' AND ')} ALLOW FILTERING`; + } + + const { + totalCount, + isEstimated, + result: preExecutedResult, + } = await this.getRowCountWithFallback(client, tableName, whereConditions, params, query); + + let result: cassandra.types.ResultSet; + if (preExecutedResult) { + result = preExecutedResult; + } else { + result = await client.execute(query, params, { prepare: true }); + } + const startIndex = (page - 1) * perPage; + + const allRows = [...result.rows]; + if (settings?.ordering_field && settings?.ordering) { + const orderingField = settings.ordering_field.toLowerCase(); + const direction = settings.ordering === QueryOrderingEnum.DESC ? -1 : 1; + + allRows.sort((a, b) => { + const valueA = a[orderingField]; + const valueB = b[orderingField]; + if (valueA === null || valueA === undefined) return direction * -1; + if (valueB === null || valueB === undefined) return direction; + if (typeof valueA === 'number' && typeof valueB === 'number') { + return (valueA - valueB) * direction; + } else if (valueA instanceof Date && valueB instanceof Date) { + return (valueA.getTime() - valueB.getTime()) * direction; + } else { + return String(valueA).localeCompare(String(valueB)) * direction; + } + }); + } + + const rows = allRows.slice(startIndex, startIndex + perPage); + + const pagination = { + total: totalCount, + lastPage: Math.ceil(totalCount / perPage), + perPage, + currentPage: page, + }; + + return { + data: rows, + pagination, + large_dataset: totalCount > DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT || isEstimated, + }; + } catch (error) { + throw new Error(`Failed to get rows from table: ${error.message}`); + } + } + + public async getTableForeignKeys(_tableName: string): Promise> { + return []; + } + private cassandraTypeToReadable(type: any): string { + if (typeof type === 'string') { + return this.stripGenerics(type); + } + + if (type && typeof type === 'object') { + if (type.info?.name) { + return this.stripGenerics(type.info.name); + } + + if (type.code !== undefined) { + switch (type.code) { + case 0: + return 'custom'; + case 1: + return 'ascii'; + case 2: + return 'bigint'; + case 3: + return 'blob'; + case 4: + return 'boolean'; + case 5: + return 'counter'; + case 6: + return 'decimal'; + case 7: + return 'double'; + case 8: + return 'float'; + case 9: + return 'int'; + case 10: + return 'text'; + case 11: + return 'timestamp'; + case 12: + return 'uuid'; + case 13: + return 'varchar'; + case 14: + return 'varint'; + case 15: + return 'timeuuid'; + case 16: + return 'inet'; + case 17: + return 'date'; + case 18: + return 'time'; + case 19: + return 'smallint'; + case 20: + return 'tinyint'; + case 21: + return 'duration'; + case 32: + return 'list'; + case 33: + return 'map'; + case 34: + return 'set'; + case 48: + return 'udt'; + case 49: + return 'tuple'; + default: + return `type_code_${type.code}`; + } + } + } + return 'unknown'; + } + + private stripGenerics(typeName: string): string { + if (typeName.includes('<')) { + return typeName.substring(0, typeName.indexOf('<')); + } + return typeName; + } + + public async getTablePrimaryColumns(tableName: string): Promise> { + try { + const client = await this.getCassandraClient(); + const keyspaceMetadata = client.metadata.keyspaces[this.connection.database]; + if (!keyspaceMetadata) { + throw new Error(`Keyspace ${this.connection.database} not found`); + } + const tableMetadata = await client.metadata.getTable(this.connection.database, tableName.toLowerCase()); + if (!tableMetadata) { + throw new Error(`Table ${tableName} not found`); + } + const primaryKeys: Array = []; + tableMetadata.partitionKeys.forEach((column) => { + primaryKeys.push({ + column_name: column.name, + data_type: this.cassandraTypeToReadable(column.type), + }); + }); + tableMetadata.clusteringKeys.forEach((column) => { + primaryKeys.push({ + column_name: column.name, + data_type: this.cassandraTypeToReadable(column.type), + }); + }); + return primaryKeys; + } catch (error) { + throw new Error(`Failed to get table primary columns: ${error.message}`); + } + } + + public async getTablesFromDB(): Promise> { + try { + const client = await this.getCassandraClient(); + const keyspace = this.connection.database; + const tables: Array = []; + const tablesResult = await client.execute( + 'SELECT table_name FROM system_schema.tables WHERE keyspace_name = ?', + [keyspace], + { prepare: true }, + ); + for (const row of tablesResult.rows) { + tables.push({ + tableName: row.table_name, + isView: false, + }); + } + const viewsResult = await client.execute( + 'SELECT view_name FROM system_schema.views WHERE keyspace_name = ?', + [keyspace], + { prepare: true }, + ); + for (const row of viewsResult.rows) { + tables.push({ + tableName: row.view_name, + isView: true, + }); + } + return tables; + } catch (error) { + throw new Error(`Failed to get tables from database: ${error.message}`); + } + } + + public async getTableStructure(tableName: string): Promise> { + try { + const client = await this.getCassandraClient(); + const tableStructure: Array = []; + const keyspace = this.connection.database; + const tableNameLower = tableName.toLowerCase(); + const columnsResult = await client.execute( + 'SELECT column_name, type, kind FROM system_schema.columns WHERE keyspace_name = ? AND table_name = ?', + [keyspace, tableNameLower], + { prepare: true }, + ); + for (const row of columnsResult.rows) { + tableStructure.push({ + column_name: row.column_name, + column_default: null, + data_type: this.cassandraTypeToReadable(row.type), + allow_null: true, + character_maximum_length: null, + data_type_params: null, + udt_name: null, + }); + } + if (tableStructure.length === 0) { + throw new Error(`Table or view ${tableName} not found`); + } + return tableStructure; + } catch (error) { + throw new Error(`Failed to get table structure: ${error.message}`); + } + } + + public async testConnect(): Promise { + try { + const client = await this.getCassandraClient(); + await client.execute('SELECT key FROM system.local'); + return { + result: true, + message: 'Successfully connected', + }; + } catch (error) { + return { + result: false, + message: `Connection failed: ${error.message}`, + }; + } + } + + public async updateRowInTable( + tableName: string, + row: Record, + primaryKey: Record, + ): Promise> { + try { + const client = await this.getCassandraClient(); + const primaryKeys = await this.getTablePrimaryColumns(tableName); + const setClause = []; + const setParams = []; + for (const [key, value] of Object.entries(row)) { + if (!primaryKeys.some((pk) => pk.column_name === key)) { + setClause.push(`${key} = ?`); + setParams.push(value); + } + } + if (setClause.length === 0) { + throw new Error('No fields to update'); + } + const whereConditions = []; + const whereParams = []; + for (const key of primaryKeys) { + const keyName = key.column_name; + if (primaryKey[keyName] !== undefined) { + whereConditions.push(`${keyName} = ?`); + whereParams.push(primaryKey[keyName]); + } + } + if (whereConditions.length === 0) { + throw new Error('No primary key values provided for update'); + } + const query = `UPDATE ${tableName} SET ${setClause.join(', ')} WHERE ${whereConditions.join(' AND ')}`; + await client.execute(query, [...setParams, ...whereParams], { prepare: true }); + return primaryKey; + } catch (error) { + throw new Error(`Failed to update row in table: ${error.message}`); + } + } + + public async bulkUpdateRowsInTable( + tableName: string, + newValues: Record, + primaryKeys: Array>, + ): Promise>> { + try { + for (const primaryKey of primaryKeys) { + await this.updateRowInTable(tableName, newValues, primaryKey); + } + return primaryKeys; + } catch (error) { + throw new Error(`Failed to bulk update rows in table: ${error.message}`); + } + } + + public async bulkDeleteRowsInTable(tableName: string, primaryKeys: Array>): Promise { + try { + let deletedCount = 0; + for (const primaryKey of primaryKeys) { + try { + await this.deleteRowInTable(tableName, primaryKey); + deletedCount++; + } catch (error) { + console.error(`Error deleting row: ${error.message}`); + } + } + return deletedCount; + } catch (error) { + throw new Error(`Failed to bulk delete rows in table: ${error.message}`); + } + } + + public async validateSettings(settings: ValidateTableSettingsDS, tableName: string): Promise> { + try { + const [tableStructure, primaryColumns] = await Promise.all([ + this.getTableStructure(tableName), + this.getTablePrimaryColumns(tableName), + ]); + return tableSettingsFieldValidator(tableStructure, primaryColumns, settings); + } catch (error) { + throw new Error(`Failed to validate settings: ${error.message}`); + } + } + + public async getReferencedTableNamesAndColumns(_tableName: string): Promise> { + return []; + } + + public async isView(tableName: string): Promise { + try { + const client = await this.getCassandraClient(); + const keyspace = this.connection.database; + const result = await client.execute( + 'SELECT view_name FROM system_schema.views WHERE keyspace_name = ? AND view_name = ?', + [keyspace, tableName.toLowerCase()], + { prepare: true }, + ); + return result.rows.length > 0; + } catch (error) { + throw new Error(`Failed to check if table is a view: ${error.message}`); + } + } + + public async getTableRowsStream( + tableName: string, + settings: TableSettingsDS, + page: number, + perPage: number, + searchedFieldValue: string, + filteringFields: Array, + ): Promise> { + try { + const result = await this.getRowsFromTable( + tableName, + settings, + page, + perPage, + searchedFieldValue, + filteringFields, + null, + null, + ); + const readable = new Readable({ + objectMode: true, + read() { + for (const row of result.data) { + this.push(row); + } + this.push(null); + }, + }); + return readable; + } catch (error) { + throw new Error(`Failed to get table rows stream: ${error.message}`); + } + } + + public async importCSVInTable(file: Express.Multer.File, tableName: string): Promise { + try { + const tableStructure = await this.getTableStructure(tableName); + const bufferStream = new Readable(); + bufferStream.push(file.buffer); + bufferStream.push(null); + const parser = csv.parse({ columns: true, trim: true }); + const rows = []; + await new Promise((resolve, reject) => { + bufferStream + .pipe(parser) + .on('data', (row) => rows.push(row)) + .on('error', (err) => reject(err)) + .on('end', () => resolve()); + }); + for (const row of rows) { + const processedRow = {}; + for (const field of tableStructure) { + const columnName = field.column_name; + + if (row[columnName] !== undefined) { + let value = row[columnName]; + if (field.data_type === 'uuid' && typeof value === 'string') { + value = value.replace(/^"+|"+$/g, ''); + } else if ( + field.data_type.includes('int') || + field.data_type.includes('float') || + field.data_type.includes('double') + ) { + value = Number.isNaN(parseFloat(value)) ? null : parseFloat(value); + } else if (field.data_type === 'timestamp' && !Number.isNaN(Number(value))) { + const timestamp = Number(value); + value = new Date(timestamp); + } else if (field.data_type.includes('boolean')) { + value = value.toLowerCase() === 'true'; + } + processedRow[columnName] = value; + } + } + + await this.addRowInTable(tableName, processedRow); + } + } catch (error) { + throw new Error(`Failed to import CSV: ${error.message}`); + } + } + + public async executeRawQuery(query: string): Promise>> { + try { + const client = await this.getCassandraClient(); + const result = await client.execute(query, [], { prepare: true }); + return result.rows; + } catch (error) { + throw new Error(`Failed to execute raw query: ${error.message}`); + } + } + + private isAWSConnection(): boolean { + const { host } = this.connection; + + if (host.includes('cassandra') && host.includes('amazonaws.com')) { + return true; + } + + if (host.includes('amazonaws.com')) { + return true; + } + + const ec2HostRegex = /^(ec2-).*([.]compute[.]amazonaws[.]com)$/i; + if (ec2HostRegex.test(host)) { + return true; + } + + return false; + } + + private async getRowCountWithFallback( + client: cassandra.Client, + tableName: string, + whereConditions: string[], + params: any[], + query: string, + ): Promise<{ totalCount: number; isEstimated: boolean; result?: cassandra.types.ResultSet }> { + const isAWS = this.isAWSConnection(); + + if (isAWS) { + return this.estimateRowCount(client, tableName, whereConditions, params, query); + } + + try { + const countQuery = + `SELECT COUNT(*) as count FROM ${tableName.toLowerCase()}` + + (whereConditions.length > 0 ? ` WHERE ${whereConditions.join(' AND ')} ALLOW FILTERING` : ''); + const countResult = await client.execute(countQuery, params, { prepare: true }); + const totalCount = parseInt(countResult.rows[0].count?.toString() || '0', 10); + return { totalCount, isEstimated: false }; + } catch (countError) { + console.warn(`COUNT query failed, falling back to estimation: ${countError.message}`); + return this.estimateRowCount(client, tableName, whereConditions, params, query); + } + } + + private async estimateRowCount( + client: cassandra.Client, + tableName: string, + whereConditions: string[], + params: any[], + query: string, + ): Promise<{ totalCount: number; isEstimated: boolean; result: cassandra.types.ResultSet }> { + try { + const result = await client.execute(query, params, { prepare: true }); + let estimatedCount = result.rows.length; + if (whereConditions.length === 0) { + try { + const sampleQuery = `SELECT * FROM ${tableName.toLowerCase()} LIMIT 10000`; + const sampleResult = await client.execute(sampleQuery, [], { prepare: true }); + + if (sampleResult.rows.length >= 10000) { + estimatedCount = Math.max(estimatedCount, sampleResult.rows.length * 2); + } else { + estimatedCount = Math.max(estimatedCount, sampleResult.rows.length); + } + } catch (sampleError) { + console.warn(`Row count sampling failed: ${sampleError.message}`); + } + } + + return { totalCount: estimatedCount, isEstimated: true, result }; + } catch (error) { + console.warn(`Row count estimation failed: ${error.message}`); + return { totalCount: 100, isEstimated: true, result: null }; + } + } + + private async getCassandraClient(): Promise { + const cachedClient = LRUStorage.getCassandraClientCache(this.connection); + + if (cachedClient) { + try { + await cachedClient.execute('SELECT key FROM system.local LIMIT 1'); + return cachedClient as cassandra.Client; + } catch (error) { + console.log(`Cached client connection failed: ${error.message}. Creating new connection.`); + try { + await cachedClient.shutdown(); + } catch (_) { + } finally { + LRUStorage.delCassandraClientCache(this.connection); + } + } + } + try { + let contactPoints = [this.connection.host]; + let port = this.connection.port; + if (this.connection.ssh) { + if (!this.connection.sshHost || !this.connection.sshPort || !this.connection.sshUsername) { + throw new Error('SSH connection requires host, port, and username'); + } + const portForSSH = await getPort(); + const tunnelConnection: any = { + host: this.connection.host, + port: this.connection.port, + sshHost: this.connection.sshHost, + sshPort: this.connection.sshPort, + sshUsername: this.connection.sshUsername, + privateSSHKey: this.connection.privateSSHKey, + }; + await getTunnel(tunnelConnection, portForSSH); + contactPoints = ['127.0.0.1']; + port = portForSSH; + } + const authProvider = new cassandra.auth.PlainTextAuthProvider(this.connection.username, this.connection.password); + const clientOptions: cassandra.ClientOptions = { + contactPoints, + localDataCenter: this.connection.dataCenter || undefined, + keyspace: this.connection.database, + authProvider, + protocolOptions: { + port, + }, + queryOptions: { + consistency: cassandra.types.consistencies.localQuorum, + }, + }; + if (this.connection.ssl) { + clientOptions.sslOptions = { + rejectUnauthorized: false, + }; + if (this.connection.cert) { + clientOptions.sslOptions.ca = [this.connection.cert]; + } + } + const client = new cassandra.Client(clientOptions); + await client.connect(); + LRUStorage.setCassandraClientCache(this.connection, client); + return client; + } catch (error) { + throw new Error(`Failed to create Cassandra client: ${error.message}`); + } + } } diff --git a/shared-code/src/data-access-layer/data-access-objects/data-access-object-clickhouse.ts b/shared-code/src/data-access-layer/data-access-objects/data-access-object-clickhouse.ts index ab8d46c42..4f8300597 100644 --- a/shared-code/src/data-access-layer/data-access-objects/data-access-object-clickhouse.ts +++ b/shared-code/src/data-access-layer/data-access-objects/data-access-object-clickhouse.ts @@ -25,300 +25,299 @@ import { BasicDataAccessObject } from './basic-data-access-object.js'; import { NodeClickHouseClientConfigOptions } from '@clickhouse/client/dist/config.js'; export class DataAccessObjectClickHouse extends BasicDataAccessObject implements IDataAccessObject { - - public async addRowInTable(tableName: string, row: Record): Promise> { - const client = await this.getClickHouseClient(); - try { - await client.insert({ - table: tableName, - values: [row], - format: 'JSONEachRow', - }); - return row; - } finally { - await client.close(); - } - } - - public async deleteRowInTable( - tableName: string, - primaryKey: Record, - ): Promise> { - const client = await this.getClickHouseClient(); - try { - const whereClause = this.buildWhereClause(primaryKey); - const query = `ALTER TABLE ${this.escapeIdentifier(tableName)} DELETE WHERE ${whereClause}`; - await client.command({ query }); - return primaryKey; - } finally { - await client.close(); - } - } - - public async getIdentityColumns( - tableName: string, - referencedFieldName: string, - identityColumnName: string, - fieldValues: Array, - ): Promise>> { - if (!referencedFieldName || !fieldValues.length) { - return []; - } - const client = await this.getClickHouseClient(); - try { - const columnsToSelect = identityColumnName - ? `${this.escapeIdentifier(referencedFieldName)}, ${this.escapeIdentifier(identityColumnName)}` - : this.escapeIdentifier(referencedFieldName); - - const placeholders = fieldValues.map((v) => this.sanitizeValue(v)).join(', '); - - const query = `SELECT ${columnsToSelect} FROM ${this.escapeIdentifier(tableName)} WHERE ${this.escapeIdentifier(referencedFieldName)} IN (${placeholders})`; - - const result = await client.query({ - query, - format: 'JSONEachRow', - }); - - return await result.json(); - } finally { - await client.close(); - } - } - - public async getRowByPrimaryKey( - tableName: string, - primaryKey: Record, - settings: TableSettingsDS, - ): Promise> { - const client = await this.getClickHouseClient(); - try { - let availableFields: string[] = []; - if (settings) { - const tableStructure = await this.getTableStructure(tableName); - availableFields = this.findAvailableFields(settings, tableStructure); - } - - const selectFields = - availableFields.length > 0 ? availableFields.map((f) => this.escapeIdentifier(f)).join(', ') : '*'; - const whereClause = this.buildWhereClause(primaryKey); - - const query = `SELECT ${selectFields} FROM ${this.escapeIdentifier(tableName)} WHERE ${whereClause} LIMIT 1`; - - const result = await client.query({ - query, - format: 'JSONEachRow', - }); - - const rows: Record[] = await result.json(); - return rows[0] || null; - } finally { - await client.close(); - } - } - - public async bulkGetRowsFromTableByPrimaryKeys( - tableName: string, - primaryKeys: Array>, - settings: TableSettingsDS, - ): Promise>> { - if (primaryKeys.length === 0) { - return []; - } - - const client = await this.getClickHouseClient(); - try { - let availableFields: string[] = []; - if (settings) { - const tableStructure = await this.getTableStructure(tableName); - availableFields = this.findAvailableFields(settings, tableStructure); - } - - const selectFields = - availableFields.length > 0 ? availableFields.map((f) => this.escapeIdentifier(f)).join(', ') : '*'; - - const whereConditions = primaryKeys.map((pk) => `(${this.buildWhereClause(pk)})`).join(' OR '); - - const query = `SELECT ${selectFields} FROM ${this.escapeIdentifier(tableName)} WHERE ${whereConditions}`; - - const result = await client.query({ - query, - format: 'JSONEachRow', - }); - - return await result.json(); - } finally { - await client.close(); - } - } - - public async getRowsFromTable( - tableName: string, - settings: TableSettingsDS, - page: number, - perPage: number, - searchedFieldValue: string, - filteringFields: Array, - autocompleteFields: AutocompleteFieldsDS, - tableStructure: TableStructureDS[] | null, - ): Promise { - page = page > 0 ? page : DAO_CONSTANTS.DEFAULT_PAGINATION.page; - perPage = - perPage > 0 - ? perPage - : settings.list_per_page > 0 - ? settings.list_per_page - : DAO_CONSTANTS.DEFAULT_PAGINATION.perPage; - - const offset = (page - 1) * perPage; - const client = await this.getClickHouseClient(); - - try { - if (!tableStructure) { - tableStructure = await this.getTableStructure(tableName); - } - const availableFields = this.findAvailableFields(settings, tableStructure); - - if (autocompleteFields?.value && autocompleteFields.fields?.length > 0) { - const { fields, value } = autocompleteFields; - const selectFields = fields.map((f) => this.escapeIdentifier(f)).join(', '); - - let whereClause = '1=1'; - if (value !== '*') { - const conditions = fields.map( - (field) => `toString(${this.escapeIdentifier(field)}) LIKE '${this.escapeValue(String(value))}%'`, - ); - whereClause = conditions.join(' OR '); - } - - const query = `SELECT ${selectFields} FROM ${this.escapeIdentifier(tableName)} WHERE ${whereClause} LIMIT ${DAO_CONSTANTS.AUTOCOMPLETE_ROW_LIMIT}`; - - const result = await client.query({ - query, - format: 'JSONEachRow', - }); - - const rows: Record[] = await result.json(); - const { large_dataset } = await this.getRowsCount(client, tableName); - - return { - data: rows, - pagination: {} as any, - large_dataset, - }; - } - - const selectFields = - availableFields.length > 0 ? availableFields.map((f) => this.escapeIdentifier(f)).join(', ') : '*'; - const whereClauses: string[] = []; - - let { search_fields } = settings; - if ((!search_fields || search_fields.length === 0) && searchedFieldValue) { - search_fields = availableFields; - } - - if (searchedFieldValue && search_fields?.length > 0) { - const searchConditions = search_fields.map( - (field) => - `lower(toString(${this.escapeIdentifier(field)})) LIKE '%${this.escapeValue(searchedFieldValue.toLowerCase())}%'`, - ); - whereClauses.push(`(${searchConditions.join(' OR ')})`); - } - - if (filteringFields?.length > 0) { - for (const filterObject of filteringFields) { - const { field, criteria, value } = filterObject; - const escapedField = this.escapeIdentifier(field); - const escapedValue = this.sanitizeValue(value); - - const escapedStringValue = this.escapeValue(String(value)); - switch (criteria) { - case FilterCriteriaEnum.eq: - whereClauses.push(`${escapedField} = ${escapedValue}`); - break; - case FilterCriteriaEnum.startswith: - whereClauses.push(`toString(${escapedField}) LIKE '${escapedStringValue}%'`); - break; - case FilterCriteriaEnum.endswith: - whereClauses.push(`toString(${escapedField}) LIKE '%${escapedStringValue}'`); - break; - case FilterCriteriaEnum.gt: - whereClauses.push(`${escapedField} > ${escapedValue}`); - break; - case FilterCriteriaEnum.lt: - whereClauses.push(`${escapedField} < ${escapedValue}`); - break; - case FilterCriteriaEnum.gte: - whereClauses.push(`${escapedField} >= ${escapedValue}`); - break; - case FilterCriteriaEnum.lte: - whereClauses.push(`${escapedField} <= ${escapedValue}`); - break; - case FilterCriteriaEnum.contains: - whereClauses.push(`toString(${escapedField}) LIKE '%${escapedStringValue}%'`); - break; - case FilterCriteriaEnum.icontains: - whereClauses.push(`toString(${escapedField}) NOT LIKE '%${escapedStringValue}%'`); - break; - case FilterCriteriaEnum.empty: - whereClauses.push(`${escapedField} IS NULL`); - break; - } - } - } - - const whereClause = whereClauses.length > 0 ? `WHERE ${whereClauses.join(' AND ')}` : ''; - const orderByClause = - settings.ordering_field && settings.ordering - ? `ORDER BY ${this.escapeIdentifier(settings.ordering_field)} ${settings.ordering}` - : ''; - - const query = `SELECT ${selectFields} FROM ${this.escapeIdentifier(tableName)} ${whereClause} ${orderByClause} LIMIT ${perPage} OFFSET ${offset}`; - - const result = await client.query({ - query, - format: 'JSONEachRow', - }); - - const rows: Record[] = await result.json(); - - const countQuery = `SELECT count(*) as count FROM ${this.escapeIdentifier(tableName)} ${whereClause}`; - const countResult = await client.query({ - query: countQuery, - format: 'JSONEachRow', - }); - const countData: Array<{ count: number }> = await countResult.json(); - const rowsCount = Number(countData[0]?.count || 0); - - const pagination = { - total: rowsCount, - lastPage: Math.ceil(rowsCount / perPage), - perPage, - currentPage: page, - }; - - return { - data: rows, - pagination, - large_dataset: rowsCount >= DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT, - }; - } finally { - await client.close(); - } - } - - public async getTableForeignKeys(_tableName: string): Promise> { - return []; - } - - public async getTablePrimaryColumns(tableName: string): Promise> { - const cachedPrimaryColumns = LRUStorage.getTablePrimaryKeysCache(this.connection, tableName); - if (cachedPrimaryColumns) { - return cachedPrimaryColumns; - } - - const client = await this.getClickHouseClient(); - try { - const query = ` + public async addRowInTable(tableName: string, row: Record): Promise> { + const client = await this.getClickHouseClient(); + try { + await client.insert({ + table: tableName, + values: [row], + format: 'JSONEachRow', + }); + return row; + } finally { + await client.close(); + } + } + + public async deleteRowInTable( + tableName: string, + primaryKey: Record, + ): Promise> { + const client = await this.getClickHouseClient(); + try { + const whereClause = this.buildWhereClause(primaryKey); + const query = `ALTER TABLE ${this.escapeIdentifier(tableName)} DELETE WHERE ${whereClause}`; + await client.command({ query }); + return primaryKey; + } finally { + await client.close(); + } + } + + public async getIdentityColumns( + tableName: string, + referencedFieldName: string, + identityColumnName: string, + fieldValues: Array, + ): Promise>> { + if (!referencedFieldName || !fieldValues.length) { + return []; + } + const client = await this.getClickHouseClient(); + try { + const columnsToSelect = identityColumnName + ? `${this.escapeIdentifier(referencedFieldName)}, ${this.escapeIdentifier(identityColumnName)}` + : this.escapeIdentifier(referencedFieldName); + + const placeholders = fieldValues.map((v) => this.sanitizeValue(v)).join(', '); + + const query = `SELECT ${columnsToSelect} FROM ${this.escapeIdentifier(tableName)} WHERE ${this.escapeIdentifier(referencedFieldName)} IN (${placeholders})`; + + const result = await client.query({ + query, + format: 'JSONEachRow', + }); + + return await result.json(); + } finally { + await client.close(); + } + } + + public async getRowByPrimaryKey( + tableName: string, + primaryKey: Record, + settings: TableSettingsDS, + ): Promise> { + const client = await this.getClickHouseClient(); + try { + let availableFields: string[] = []; + if (settings) { + const tableStructure = await this.getTableStructure(tableName); + availableFields = this.findAvailableFields(settings, tableStructure); + } + + const selectFields = + availableFields.length > 0 ? availableFields.map((f) => this.escapeIdentifier(f)).join(', ') : '*'; + const whereClause = this.buildWhereClause(primaryKey); + + const query = `SELECT ${selectFields} FROM ${this.escapeIdentifier(tableName)} WHERE ${whereClause} LIMIT 1`; + + const result = await client.query({ + query, + format: 'JSONEachRow', + }); + + const rows: Record[] = await result.json(); + return rows[0] || null; + } finally { + await client.close(); + } + } + + public async bulkGetRowsFromTableByPrimaryKeys( + tableName: string, + primaryKeys: Array>, + settings: TableSettingsDS, + ): Promise>> { + if (primaryKeys.length === 0) { + return []; + } + + const client = await this.getClickHouseClient(); + try { + let availableFields: string[] = []; + if (settings) { + const tableStructure = await this.getTableStructure(tableName); + availableFields = this.findAvailableFields(settings, tableStructure); + } + + const selectFields = + availableFields.length > 0 ? availableFields.map((f) => this.escapeIdentifier(f)).join(', ') : '*'; + + const whereConditions = primaryKeys.map((pk) => `(${this.buildWhereClause(pk)})`).join(' OR '); + + const query = `SELECT ${selectFields} FROM ${this.escapeIdentifier(tableName)} WHERE ${whereConditions}`; + + const result = await client.query({ + query, + format: 'JSONEachRow', + }); + + return await result.json(); + } finally { + await client.close(); + } + } + + public async getRowsFromTable( + tableName: string, + settings: TableSettingsDS, + page: number, + perPage: number, + searchedFieldValue: string, + filteringFields: Array, + autocompleteFields: AutocompleteFieldsDS, + tableStructure: TableStructureDS[] | null, + ): Promise { + page = page > 0 ? page : DAO_CONSTANTS.DEFAULT_PAGINATION.page; + perPage = + perPage > 0 + ? perPage + : settings.list_per_page > 0 + ? settings.list_per_page + : DAO_CONSTANTS.DEFAULT_PAGINATION.perPage; + + const offset = (page - 1) * perPage; + const client = await this.getClickHouseClient(); + + try { + if (!tableStructure) { + tableStructure = await this.getTableStructure(tableName); + } + const availableFields = this.findAvailableFields(settings, tableStructure); + + if (autocompleteFields?.value && autocompleteFields.fields?.length > 0) { + const { fields, value } = autocompleteFields; + const selectFields = fields.map((f) => this.escapeIdentifier(f)).join(', '); + + let whereClause = '1=1'; + if (value !== '*') { + const conditions = fields.map( + (field) => `toString(${this.escapeIdentifier(field)}) LIKE '${this.escapeValue(String(value))}%'`, + ); + whereClause = conditions.join(' OR '); + } + + const query = `SELECT ${selectFields} FROM ${this.escapeIdentifier(tableName)} WHERE ${whereClause} LIMIT ${DAO_CONSTANTS.AUTOCOMPLETE_ROW_LIMIT}`; + + const result = await client.query({ + query, + format: 'JSONEachRow', + }); + + const rows: Record[] = await result.json(); + const { large_dataset } = await this.getRowsCount(client, tableName); + + return { + data: rows, + pagination: {} as any, + large_dataset, + }; + } + + const selectFields = + availableFields.length > 0 ? availableFields.map((f) => this.escapeIdentifier(f)).join(', ') : '*'; + const whereClauses: string[] = []; + + let { search_fields } = settings; + if ((!search_fields || search_fields.length === 0) && searchedFieldValue) { + search_fields = availableFields; + } + + if (searchedFieldValue && search_fields?.length > 0) { + const searchConditions = search_fields.map( + (field) => + `lower(toString(${this.escapeIdentifier(field)})) LIKE '%${this.escapeValue(searchedFieldValue.toLowerCase())}%'`, + ); + whereClauses.push(`(${searchConditions.join(' OR ')})`); + } + + if (filteringFields?.length > 0) { + for (const filterObject of filteringFields) { + const { field, criteria, value } = filterObject; + const escapedField = this.escapeIdentifier(field); + const escapedValue = this.sanitizeValue(value); + + const escapedStringValue = this.escapeValue(String(value)); + switch (criteria) { + case FilterCriteriaEnum.eq: + whereClauses.push(`${escapedField} = ${escapedValue}`); + break; + case FilterCriteriaEnum.startswith: + whereClauses.push(`toString(${escapedField}) LIKE '${escapedStringValue}%'`); + break; + case FilterCriteriaEnum.endswith: + whereClauses.push(`toString(${escapedField}) LIKE '%${escapedStringValue}'`); + break; + case FilterCriteriaEnum.gt: + whereClauses.push(`${escapedField} > ${escapedValue}`); + break; + case FilterCriteriaEnum.lt: + whereClauses.push(`${escapedField} < ${escapedValue}`); + break; + case FilterCriteriaEnum.gte: + whereClauses.push(`${escapedField} >= ${escapedValue}`); + break; + case FilterCriteriaEnum.lte: + whereClauses.push(`${escapedField} <= ${escapedValue}`); + break; + case FilterCriteriaEnum.contains: + whereClauses.push(`toString(${escapedField}) LIKE '%${escapedStringValue}%'`); + break; + case FilterCriteriaEnum.icontains: + whereClauses.push(`toString(${escapedField}) NOT LIKE '%${escapedStringValue}%'`); + break; + case FilterCriteriaEnum.empty: + whereClauses.push(`${escapedField} IS NULL`); + break; + } + } + } + + const whereClause = whereClauses.length > 0 ? `WHERE ${whereClauses.join(' AND ')}` : ''; + const orderByClause = + settings.ordering_field && settings.ordering + ? `ORDER BY ${this.escapeIdentifier(settings.ordering_field)} ${settings.ordering}` + : ''; + + const query = `SELECT ${selectFields} FROM ${this.escapeIdentifier(tableName)} ${whereClause} ${orderByClause} LIMIT ${perPage} OFFSET ${offset}`; + + const result = await client.query({ + query, + format: 'JSONEachRow', + }); + + const rows: Record[] = await result.json(); + + const countQuery = `SELECT count(*) as count FROM ${this.escapeIdentifier(tableName)} ${whereClause}`; + const countResult = await client.query({ + query: countQuery, + format: 'JSONEachRow', + }); + const countData: Array<{ count: number }> = await countResult.json(); + const rowsCount = Number(countData[0]?.count || 0); + + const pagination = { + total: rowsCount, + lastPage: Math.ceil(rowsCount / perPage), + perPage, + currentPage: page, + }; + + return { + data: rows, + pagination, + large_dataset: rowsCount >= DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT, + }; + } finally { + await client.close(); + } + } + + public async getTableForeignKeys(_tableName: string): Promise> { + return []; + } + + public async getTablePrimaryColumns(tableName: string): Promise> { + const cachedPrimaryColumns = LRUStorage.getTablePrimaryKeysCache(this.connection, tableName); + if (cachedPrimaryColumns) { + return cachedPrimaryColumns; + } + + const client = await this.getClickHouseClient(); + try { + const query = ` SELECT name, type FROM system.columns WHERE database = '${this.escapeValue(this.connection.database || 'default')}' @@ -327,30 +326,30 @@ export class DataAccessObjectClickHouse extends BasicDataAccessObject implements ORDER BY position `; - const result = await client.query({ - query, - format: 'JSONEachRow', - }); - - const columns: Array<{ name: string; type: string }> = await result.json(); - - const resultKeys = columns.map((column) => ({ - column_name: column.name, - data_type: this.mapClickHouseType(column.type), - })); - - LRUStorage.setTablePrimaryKeysCache(this.connection, tableName, resultKeys); - return resultKeys; - } finally { - await client.close(); - } - } - - public async getTablesFromDB(): Promise> { - const client = await this.getClickHouseClient(); - try { - const database = this.connection.database || 'default'; - const query = ` + const result = await client.query({ + query, + format: 'JSONEachRow', + }); + + const columns: Array<{ name: string; type: string }> = await result.json(); + + const resultKeys = columns.map((column) => ({ + column_name: column.name, + data_type: this.mapClickHouseType(column.type), + })); + + LRUStorage.setTablePrimaryKeysCache(this.connection, tableName, resultKeys); + return resultKeys; + } finally { + await client.close(); + } + } + + public async getTablesFromDB(): Promise> { + const client = await this.getClickHouseClient(); + try { + const database = this.connection.database || 'default'; + const query = ` SELECT name, engine FROM system.tables WHERE database = '${this.escapeValue(database)}' @@ -358,32 +357,32 @@ export class DataAccessObjectClickHouse extends BasicDataAccessObject implements ORDER BY name `; - const result = await client.query({ - query, - format: 'JSONEachRow', - }); - - const tables: Array<{ name: string; engine: string }> = await result.json(); - - return tables.map((table) => ({ - tableName: table.name, - isView: table.engine === 'View' || table.engine === 'MaterializedView', - })); - } finally { - await client.close(); - } - } - - public async getTableStructure(tableName: string): Promise> { - const cachedTableStructure = LRUStorage.getTableStructureCache(this.connection, tableName); - if (cachedTableStructure) { - return cachedTableStructure; - } - - const client = await this.getClickHouseClient(); - try { - const database = this.connection.database || 'default'; - const query = ` + const result = await client.query({ + query, + format: 'JSONEachRow', + }); + + const tables: Array<{ name: string; engine: string }> = await result.json(); + + return tables.map((table) => ({ + tableName: table.name, + isView: table.engine === 'View' || table.engine === 'MaterializedView', + })); + } finally { + await client.close(); + } + } + + public async getTableStructure(tableName: string): Promise> { + const cachedTableStructure = LRUStorage.getTableStructureCache(this.connection, tableName); + if (cachedTableStructure) { + return cachedTableStructure; + } + + const client = await this.getClickHouseClient(); + try { + const database = this.connection.database || 'default'; + const query = ` SELECT name, type, @@ -396,508 +395,508 @@ export class DataAccessObjectClickHouse extends BasicDataAccessObject implements ORDER BY position `; - const result = await client.query({ - query, - format: 'JSONEachRow', - }); - - const columns: Array<{ - name: string; - type: string; - default_kind: string; - default_expression: string; - is_in_primary_key: number; - }> = await result.json(); - - const structure: TableStructureDS[] = columns.map((column) => ({ - column_name: column.name, - data_type: this.mapClickHouseType(column.type), - column_default: column.default_expression || null, - allow_null: this.isNullableType(column.type), - character_maximum_length: this.extractLength(column.type), - data_type_params: this.extractTypeParams(column.type), - udt_name: column.type, - extra: this.buildExtraInfo(column.is_in_primary_key, column.default_expression), - })); - - LRUStorage.setTableStructureCache(this.connection, tableName, structure); - return structure; - } finally { - await client.close(); - } - } - - public async testConnect(): Promise { - const client = await this.getClickHouseClient(); - try { - const result = await client.query({ - query: 'SELECT 1', - format: 'JSONEachRow', - }); - await result.json(); - - return { - result: true, - message: 'Successfully connected', - }; - } catch (e) { - return { - result: false, - message: e.message || 'Connection failed', - }; - } finally { - await client.close(); - } - } - - public async updateRowInTable( - tableName: string, - row: Record, - primaryKey: Record, - ): Promise> { - const client = await this.getClickHouseClient(); - try { - const setClause = Object.entries(row) - .map(([key, value]) => { - const sanitizedValue = this.sanitizeValue(value); - return `${this.escapeIdentifier(key)} = ${sanitizedValue}`; - }) - .join(', '); - - const whereClause = this.buildWhereClause(primaryKey); - - const query = `ALTER TABLE ${this.escapeIdentifier(tableName)} UPDATE ${setClause} WHERE ${whereClause}`; - await client.command({ query }); - - return primaryKey; - } finally { - await client.close(); - } - } - - public async bulkUpdateRowsInTable( - tableName: string, - newValues: Record, - primaryKeys: Array>, - ): Promise>> { - if (primaryKeys.length === 0) { - return []; - } - - const client = await this.getClickHouseClient(); - try { - const setClause = Object.entries(newValues) - .map(([key, value]) => { - const sanitizedValue = this.sanitizeValue(value); - return `${this.escapeIdentifier(key)} = ${sanitizedValue}`; - }) - .join(', '); - - const whereConditions = primaryKeys.map((pk) => `(${this.buildWhereClause(pk)})`).join(' OR '); - - const query = `ALTER TABLE ${this.escapeIdentifier(tableName)} UPDATE ${setClause} WHERE ${whereConditions}`; - await client.command({ query }); - - return primaryKeys; - } finally { - await client.close(); - } - } - - public async bulkDeleteRowsInTable(tableName: string, primaryKeys: Array>): Promise { - if (primaryKeys.length === 0) { - return 0; - } - - const client = await this.getClickHouseClient(); - try { - const whereConditions = primaryKeys.map((pk) => `(${this.buildWhereClause(pk)})`).join(' OR '); - - const query = `ALTER TABLE ${this.escapeIdentifier(tableName)} DELETE WHERE ${whereConditions}`; - await client.command({ query }); - - return primaryKeys.length; - } finally { - await client.close(); - } - } - - public async validateSettings(settings: ValidateTableSettingsDS, tableName: string): Promise> { - const [tableStructure, primaryColumns] = await Promise.all([ - this.getTableStructure(tableName), - this.getTablePrimaryColumns(tableName), - ]); - return tableSettingsFieldValidator(tableStructure, primaryColumns, settings); - } - - public async getReferencedTableNamesAndColumns(_tableName: string): Promise> { - return []; - } - - public async isView(tableName: string): Promise { - const client = await this.getClickHouseClient(); - try { - const database = this.connection.database || 'default'; - const query = ` + const result = await client.query({ + query, + format: 'JSONEachRow', + }); + + const columns: Array<{ + name: string; + type: string; + default_kind: string; + default_expression: string; + is_in_primary_key: number; + }> = await result.json(); + + const structure: TableStructureDS[] = columns.map((column) => ({ + column_name: column.name, + data_type: this.mapClickHouseType(column.type), + column_default: column.default_expression || null, + allow_null: this.isNullableType(column.type), + character_maximum_length: this.extractLength(column.type), + data_type_params: this.extractTypeParams(column.type), + udt_name: column.type, + extra: this.buildExtraInfo(column.is_in_primary_key, column.default_expression), + })); + + LRUStorage.setTableStructureCache(this.connection, tableName, structure); + return structure; + } finally { + await client.close(); + } + } + + public async testConnect(): Promise { + const client = await this.getClickHouseClient(); + try { + const result = await client.query({ + query: 'SELECT 1', + format: 'JSONEachRow', + }); + await result.json(); + + return { + result: true, + message: 'Successfully connected', + }; + } catch (e) { + return { + result: false, + message: e.message || 'Connection failed', + }; + } finally { + await client.close(); + } + } + + public async updateRowInTable( + tableName: string, + row: Record, + primaryKey: Record, + ): Promise> { + const client = await this.getClickHouseClient(); + try { + const setClause = Object.entries(row) + .map(([key, value]) => { + const sanitizedValue = this.sanitizeValue(value); + return `${this.escapeIdentifier(key)} = ${sanitizedValue}`; + }) + .join(', '); + + const whereClause = this.buildWhereClause(primaryKey); + + const query = `ALTER TABLE ${this.escapeIdentifier(tableName)} UPDATE ${setClause} WHERE ${whereClause}`; + await client.command({ query }); + + return primaryKey; + } finally { + await client.close(); + } + } + + public async bulkUpdateRowsInTable( + tableName: string, + newValues: Record, + primaryKeys: Array>, + ): Promise>> { + if (primaryKeys.length === 0) { + return []; + } + + const client = await this.getClickHouseClient(); + try { + const setClause = Object.entries(newValues) + .map(([key, value]) => { + const sanitizedValue = this.sanitizeValue(value); + return `${this.escapeIdentifier(key)} = ${sanitizedValue}`; + }) + .join(', '); + + const whereConditions = primaryKeys.map((pk) => `(${this.buildWhereClause(pk)})`).join(' OR '); + + const query = `ALTER TABLE ${this.escapeIdentifier(tableName)} UPDATE ${setClause} WHERE ${whereConditions}`; + await client.command({ query }); + + return primaryKeys; + } finally { + await client.close(); + } + } + + public async bulkDeleteRowsInTable(tableName: string, primaryKeys: Array>): Promise { + if (primaryKeys.length === 0) { + return 0; + } + + const client = await this.getClickHouseClient(); + try { + const whereConditions = primaryKeys.map((pk) => `(${this.buildWhereClause(pk)})`).join(' OR '); + + const query = `ALTER TABLE ${this.escapeIdentifier(tableName)} DELETE WHERE ${whereConditions}`; + await client.command({ query }); + + return primaryKeys.length; + } finally { + await client.close(); + } + } + + public async validateSettings(settings: ValidateTableSettingsDS, tableName: string): Promise> { + const [tableStructure, primaryColumns] = await Promise.all([ + this.getTableStructure(tableName), + this.getTablePrimaryColumns(tableName), + ]); + return tableSettingsFieldValidator(tableStructure, primaryColumns, settings); + } + + public async getReferencedTableNamesAndColumns(_tableName: string): Promise> { + return []; + } + + public async isView(tableName: string): Promise { + const client = await this.getClickHouseClient(); + try { + const database = this.connection.database || 'default'; + const query = ` SELECT engine FROM system.tables WHERE database = '${this.escapeValue(database)}' AND name = '${this.escapeValue(tableName)}' `; - const result = await client.query({ - query, - format: 'JSONEachRow', - }); - - const tables: Array<{ engine: string }> = await result.json(); - - if (tables.length === 0) { - throw new Error(ERROR_MESSAGES.TABLE_NOT_FOUND(tableName)); - } - - return tables[0].engine === 'View' || tables[0].engine === 'MaterializedView'; - } finally { - await client.close(); - } - } - - public async getTableRowsStream( - tableName: string, - settings: TableSettingsDS, - page: number, - perPage: number, - searchedFieldValue: string, - filteringFields: Array, - ): Promise> { - const result = await this.getRowsFromTable( - tableName, - settings, - page, - perPage, - searchedFieldValue, - filteringFields, - null, - null, - ); - - const stream = new Readable({ - objectMode: true, - read() { - for (const row of result.data) { - this.push(row); - } - this.push(null); - }, - }); - - return stream as Stream & AsyncIterable; - } - - public async importCSVInTable(file: Express.Multer.File, tableName: string): Promise { - const client = await this.getClickHouseClient(); - try { - const stream = new Readable(); - stream.push(file.buffer); - stream.push(null); - - const parser = stream.pipe(csv.parse({ columns: true })); - - const rows: any[] = []; - for await (const record of parser) { - rows.push(record); - } - - if (rows.length > 0) { - await client.insert({ - table: tableName, - values: rows, - format: 'JSONEachRow', - }); - } - } finally { - await client.close(); - } - } - - public async executeRawQuery(query: string, _tableName?: string): Promise>> { - const client = await this.getClickHouseClient(); - try { - const result = await client.query({ - query, - format: 'JSONEachRow', - }); - - return await result.json(); - } finally { - await client.close(); - } - } - - private escapeIdentifier(identifier: string): string { - this.validateIdentifier(identifier); - return `\`${identifier.replace(/`/g, '``')}\``; - } - - private validateIdentifier(identifier: string): void { - if (!identifier || typeof identifier !== 'string') { - throw new Error('Invalid identifier: must be a non-empty string'); - } - - if (identifier.length > 256) { - throw new Error('Invalid identifier: exceeds maximum length'); - } - - if (/[\x00-\x1f\x7f]/.test(identifier)) { - throw new Error('Invalid identifier: contains control characters'); - } - } - - private escapeValue(value: string): string { - if (typeof value !== 'string') { - throw new Error('escapeValue expects a string'); - } - return value - .replace(/\\/g, '\\\\') - .replace(/'/g, "''") - .replace(/\0/g, '\\0') - .replace(/\n/g, '\\n') - .replace(/\r/g, '\\r') - .replace(/\x1a/g, '\\Z'); - } - - private sanitizeValue(value: unknown): string { - if (value === null || value === undefined) { - return 'NULL'; - } - if (typeof value === 'number') { - if (!Number.isFinite(value)) { - throw new Error('Invalid numeric value: must be finite'); - } - return String(value); - } - if (typeof value === 'boolean') { - return value ? '1' : '0'; - } - if (typeof value === 'string') { - return `'${this.escapeValue(value)}'`; - } - if (value instanceof Date) { - return `'${this.escapeValue(value.toISOString())}'`; - } - - if (typeof value === 'object') { - return `'${this.escapeValue(JSON.stringify(value))}'`; - } - throw new Error(`Unsupported value type: ${typeof value}`); - } - - private buildWhereClause(conditions: Record): string { - if (!conditions || typeof conditions !== 'object') { - throw new Error('Invalid conditions: must be an object'); - } - const entries = Object.entries(conditions); - if (entries.length === 0) { - throw new Error('Invalid conditions: must have at least one condition'); - } - return entries - .map(([key, value]) => { - const sanitizedValue = this.sanitizeValue(value); - return `${this.escapeIdentifier(key)} = ${sanitizedValue}`; - }) - .join(' AND '); - } - - private mapClickHouseType(clickHouseType: string): string { - const lowerType = clickHouseType.toLowerCase(); - - if (lowerType.startsWith('nullable(')) { - return this.mapClickHouseType(clickHouseType.slice(9, -1)); - } - - if (lowerType.startsWith('array(')) { - return 'array'; - } - - if (lowerType.startsWith('map(')) { - return 'object'; - } - - if (lowerType.startsWith('tuple(')) { - return 'object'; - } - - if (lowerType.startsWith('enum')) { - return 'enum'; - } - - if (lowerType.startsWith('fixedstring')) { - return 'string'; - } - - if (lowerType.startsWith('decimal')) { - return 'decimal'; - } - - const typeMapping: Record = { - string: 'string', - uuid: 'uuid', - bool: 'boolean', - boolean: 'boolean', - int8: 'integer', - int16: 'integer', - int32: 'integer', - int64: 'bigint', - int128: 'bigint', - int256: 'bigint', - uint8: 'integer', - uint16: 'integer', - uint32: 'integer', - uint64: 'bigint', - uint128: 'bigint', - uint256: 'bigint', - float32: 'float', - float64: 'double', - date: 'date', - date32: 'date', - datetime: 'datetime', - datetime64: 'datetime', - ipv4: 'string', - ipv6: 'string', - json: 'json', - object: 'object', - }; - - return typeMapping[lowerType] || 'string'; - } - - private isNullableType(type: string): boolean { - return type.toLowerCase().startsWith('nullable('); - } - - private extractLength(type: string): number | null { - const fixedStringMatch = type.match(/FixedString\((\d+)\)/i); - if (fixedStringMatch) { - return parseInt(fixedStringMatch[1], 10); - } - return null; - } - - private extractTypeParams(type: string): string | null { - const enumMatch = type.match(/Enum\d*\(([^)]+)\)/i); - if (enumMatch) { - return enumMatch[1]; - } - return null; - } - - private buildExtraInfo(isPrimaryKey: number, defaultExpression: string): string | undefined { - const parts: string[] = []; - if (isPrimaryKey) { - parts.push('primary_key'); - } - - if (defaultExpression) { - const lowerDefault = defaultExpression.toLowerCase(); - if ( - lowerDefault.includes('generateuuidv4') || - lowerDefault.includes('generateuuid') || - lowerDefault.includes('rownumberinallblocks') || - lowerDefault.includes('rownumber') || - lowerDefault.includes('auto_increment') || - lowerDefault.includes('autoincrement') || - lowerDefault.includes('nextval') || - lowerDefault.includes('generate') - ) { - parts.push('auto_increment'); - } - } - return parts.length > 0 ? parts.join(' ') : undefined; - } - - private async getRowsCount( - client: ClickHouseClient, - tableName: string, - ): Promise<{ rowsCount: number; large_dataset: boolean }> { - const query = `SELECT count(*) as count FROM ${this.escapeIdentifier(tableName)}`; - const result = await client.query({ - query, - format: 'JSONEachRow', - }); - const data: Array<{ count: number }> = await result.json(); - const count = Number(data[0]?.count || 0); - - return { - rowsCount: count, - large_dataset: count >= DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT, - }; - } - - private async getClickHouseClient(): Promise { - if (this.connection.ssh) { - return this.createTunneledClickHouseClient(); - } - return this.createDirectClickHouseClient(this.connection.host, this.connection.port); - } - - private createDirectClickHouseClient(host: string, port: number): ClickHouseClient { - const { username, password, database, ssl, cert } = this.connection; - const protocol = ssl ? 'https' : 'http'; - const url = `${protocol}://${host}:${port}`; - - const clientConfig: NodeClickHouseClientConfigOptions = { - url, - username, - password, - database: database || 'default', - }; - - if (ssl && cert) { - clientConfig.tls = { - ca_cert: Buffer.from(cert), - }; - } - - return createClient(clientConfig); - } - - private async createTunneledClickHouseClient(): Promise { - const connectionCopy = { ...this.connection }; - - const cachedTnl = LRUStorage.getTunnelCache(connectionCopy); - if (cachedTnl?.clickhouse && cachedTnl.server && cachedTnl.client) { - return cachedTnl.clickhouse; - } - - const freePort = await getPort(); - - return new Promise(async (resolve, reject): Promise => { - try { - const [server, client] = await getTunnel(connectionCopy, freePort); - const clickhouseClient = this.createDirectClickHouseClient('127.0.0.1', freePort); - - const tnlCachedObj = { - server: server, - client: client, - clickhouse: clickhouseClient, - }; - - LRUStorage.setTunnelCache(connectionCopy, tnlCachedObj); - resolve(clickhouseClient); - - client.on('error', (e) => { - LRUStorage.delTunnelCache(connectionCopy); - reject(e); - }); - - server.on('error', (e) => { - LRUStorage.delTunnelCache(connectionCopy); - reject(e); - }); - } catch (error) { - LRUStorage.delTunnelCache(connectionCopy); - reject(error); - } - }); - } + const result = await client.query({ + query, + format: 'JSONEachRow', + }); + + const tables: Array<{ engine: string }> = await result.json(); + + if (tables.length === 0) { + throw new Error(ERROR_MESSAGES.TABLE_NOT_FOUND(tableName)); + } + + return tables[0].engine === 'View' || tables[0].engine === 'MaterializedView'; + } finally { + await client.close(); + } + } + + public async getTableRowsStream( + tableName: string, + settings: TableSettingsDS, + page: number, + perPage: number, + searchedFieldValue: string, + filteringFields: Array, + ): Promise> { + const result = await this.getRowsFromTable( + tableName, + settings, + page, + perPage, + searchedFieldValue, + filteringFields, + null, + null, + ); + + const stream = new Readable({ + objectMode: true, + read() { + for (const row of result.data) { + this.push(row); + } + this.push(null); + }, + }); + + return stream as Stream & AsyncIterable; + } + + public async importCSVInTable(file: Express.Multer.File, tableName: string): Promise { + const client = await this.getClickHouseClient(); + try { + const stream = new Readable(); + stream.push(file.buffer); + stream.push(null); + + const parser = stream.pipe(csv.parse({ columns: true })); + + const rows: any[] = []; + for await (const record of parser) { + rows.push(record); + } + + if (rows.length > 0) { + await client.insert({ + table: tableName, + values: rows, + format: 'JSONEachRow', + }); + } + } finally { + await client.close(); + } + } + + public async executeRawQuery(query: string, _tableName?: string): Promise>> { + const client = await this.getClickHouseClient(); + try { + const result = await client.query({ + query, + format: 'JSONEachRow', + }); + + return await result.json(); + } finally { + await client.close(); + } + } + + private escapeIdentifier(identifier: string): string { + this.validateIdentifier(identifier); + return `\`${identifier.replace(/`/g, '``')}\``; + } + + private validateIdentifier(identifier: string): void { + if (!identifier || typeof identifier !== 'string') { + throw new Error('Invalid identifier: must be a non-empty string'); + } + + if (identifier.length > 256) { + throw new Error('Invalid identifier: exceeds maximum length'); + } + + if (/[\x00-\x1f\x7f]/.test(identifier)) { + throw new Error('Invalid identifier: contains control characters'); + } + } + + private escapeValue(value: string): string { + if (typeof value !== 'string') { + throw new Error('escapeValue expects a string'); + } + return value + .replace(/\\/g, '\\\\') + .replace(/'/g, "''") + .replace(/\0/g, '\\0') + .replace(/\n/g, '\\n') + .replace(/\r/g, '\\r') + .replace(/\x1a/g, '\\Z'); + } + + private sanitizeValue(value: unknown): string { + if (value === null || value === undefined) { + return 'NULL'; + } + if (typeof value === 'number') { + if (!Number.isFinite(value)) { + throw new Error('Invalid numeric value: must be finite'); + } + return String(value); + } + if (typeof value === 'boolean') { + return value ? '1' : '0'; + } + if (typeof value === 'string') { + return `'${this.escapeValue(value)}'`; + } + if (value instanceof Date) { + return `'${this.escapeValue(value.toISOString())}'`; + } + + if (typeof value === 'object') { + return `'${this.escapeValue(JSON.stringify(value))}'`; + } + throw new Error(`Unsupported value type: ${typeof value}`); + } + + private buildWhereClause(conditions: Record): string { + if (!conditions || typeof conditions !== 'object') { + throw new Error('Invalid conditions: must be an object'); + } + const entries = Object.entries(conditions); + if (entries.length === 0) { + throw new Error('Invalid conditions: must have at least one condition'); + } + return entries + .map(([key, value]) => { + const sanitizedValue = this.sanitizeValue(value); + return `${this.escapeIdentifier(key)} = ${sanitizedValue}`; + }) + .join(' AND '); + } + + private mapClickHouseType(clickHouseType: string): string { + const lowerType = clickHouseType.toLowerCase(); + + if (lowerType.startsWith('nullable(')) { + return this.mapClickHouseType(clickHouseType.slice(9, -1)); + } + + if (lowerType.startsWith('array(')) { + return 'array'; + } + + if (lowerType.startsWith('map(')) { + return 'object'; + } + + if (lowerType.startsWith('tuple(')) { + return 'object'; + } + + if (lowerType.startsWith('enum')) { + return 'enum'; + } + + if (lowerType.startsWith('fixedstring')) { + return 'string'; + } + + if (lowerType.startsWith('decimal')) { + return 'decimal'; + } + + const typeMapping: Record = { + string: 'string', + uuid: 'uuid', + bool: 'boolean', + boolean: 'boolean', + int8: 'integer', + int16: 'integer', + int32: 'integer', + int64: 'bigint', + int128: 'bigint', + int256: 'bigint', + uint8: 'integer', + uint16: 'integer', + uint32: 'integer', + uint64: 'bigint', + uint128: 'bigint', + uint256: 'bigint', + float32: 'float', + float64: 'double', + date: 'date', + date32: 'date', + datetime: 'datetime', + datetime64: 'datetime', + ipv4: 'string', + ipv6: 'string', + json: 'json', + object: 'object', + }; + + return typeMapping[lowerType] || 'string'; + } + + private isNullableType(type: string): boolean { + return type.toLowerCase().startsWith('nullable('); + } + + private extractLength(type: string): number | null { + const fixedStringMatch = type.match(/FixedString\((\d+)\)/i); + if (fixedStringMatch) { + return parseInt(fixedStringMatch[1], 10); + } + return null; + } + + private extractTypeParams(type: string): string | null { + const enumMatch = type.match(/Enum\d*\(([^)]+)\)/i); + if (enumMatch) { + return enumMatch[1]; + } + return null; + } + + private buildExtraInfo(isPrimaryKey: number, defaultExpression: string): string | undefined { + const parts: string[] = []; + if (isPrimaryKey) { + parts.push('primary_key'); + } + + if (defaultExpression) { + const lowerDefault = defaultExpression.toLowerCase(); + if ( + lowerDefault.includes('generateuuidv4') || + lowerDefault.includes('generateuuid') || + lowerDefault.includes('rownumberinallblocks') || + lowerDefault.includes('rownumber') || + lowerDefault.includes('auto_increment') || + lowerDefault.includes('autoincrement') || + lowerDefault.includes('nextval') || + lowerDefault.includes('generate') + ) { + parts.push('auto_increment'); + } + } + return parts.length > 0 ? parts.join(' ') : undefined; + } + + private async getRowsCount( + client: ClickHouseClient, + tableName: string, + ): Promise<{ rowsCount: number; large_dataset: boolean }> { + const query = `SELECT count(*) as count FROM ${this.escapeIdentifier(tableName)}`; + const result = await client.query({ + query, + format: 'JSONEachRow', + }); + const data: Array<{ count: number }> = await result.json(); + const count = Number(data[0]?.count || 0); + + return { + rowsCount: count, + large_dataset: count >= DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT, + }; + } + + private async getClickHouseClient(): Promise { + if (this.connection.ssh) { + return this.createTunneledClickHouseClient(); + } + return this.createDirectClickHouseClient(this.connection.host, this.connection.port); + } + + private createDirectClickHouseClient(host: string, port: number): ClickHouseClient { + const { username, password, database, ssl, cert } = this.connection; + const protocol = ssl ? 'https' : 'http'; + const url = `${protocol}://${host}:${port}`; + + const clientConfig: NodeClickHouseClientConfigOptions = { + url, + username, + password, + database: database || 'default', + }; + + if (ssl && cert) { + clientConfig.tls = { + ca_cert: Buffer.from(cert), + }; + } + + return createClient(clientConfig); + } + + private async createTunneledClickHouseClient(): Promise { + const connectionCopy = { ...this.connection }; + + const cachedTnl = LRUStorage.getTunnelCache(connectionCopy); + if (cachedTnl?.clickhouse && cachedTnl.server && cachedTnl.client) { + return cachedTnl.clickhouse; + } + + const freePort = await getPort(); + + return new Promise(async (resolve, reject): Promise => { + try { + const [server, client] = await getTunnel(connectionCopy, freePort); + const clickhouseClient = this.createDirectClickHouseClient('127.0.0.1', freePort); + + const tnlCachedObj = { + server: server, + client: client, + clickhouse: clickhouseClient, + }; + + LRUStorage.setTunnelCache(connectionCopy, tnlCachedObj); + resolve(clickhouseClient); + + client.on('error', (e) => { + LRUStorage.delTunnelCache(connectionCopy); + reject(e); + }); + + server.on('error', (e) => { + LRUStorage.delTunnelCache(connectionCopy); + reject(e); + }); + } catch (error) { + LRUStorage.delTunnelCache(connectionCopy); + reject(error); + } + }); + } } diff --git a/shared-code/src/data-access-layer/data-access-objects/data-access-object-dynamodb.ts b/shared-code/src/data-access-layer/data-access-objects/data-access-object-dynamodb.ts index 4d43edf4f..d19d0fa04 100644 --- a/shared-code/src/data-access-layer/data-access-objects/data-access-object-dynamodb.ts +++ b/shared-code/src/data-access-layer/data-access-objects/data-access-object-dynamodb.ts @@ -1,12 +1,12 @@ /* eslint-disable security/detect-object-injection */ import { - DeleteItemCommand, - DynamoDB, - GetItemCommand, - PutItemCommand, - ScanCommand, - UpdateItemCommand, - BatchGetItemCommand, + DeleteItemCommand, + DynamoDB, + GetItemCommand, + PutItemCommand, + ScanCommand, + UpdateItemCommand, + BatchGetItemCommand, } from '@aws-sdk/client-dynamodb'; import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb'; import { marshall } from '@aws-sdk/util-dynamodb'; @@ -33,860 +33,858 @@ import { IDataAccessObject } from '../../shared/interfaces/data-access-object.in import { BasicDataAccessObject } from './basic-data-access-object.js'; export type DdAndClient = { - dynamoDb: DynamoDB; - documentClient: DynamoDBDocumentClient; + dynamoDb: DynamoDB; + documentClient: DynamoDBDocumentClient; }; export class DataAccessObjectDynamoDB extends BasicDataAccessObject implements IDataAccessObject { - - public async addRowInTable( - tableName: string, - row: Record, - ): Promise | number> { - try { - const tableStructure = await this.getTableStructure(tableName); - row = this.convertHexDataToBinaryInBinarySets(row, tableStructure); - const { documentClient } = this.getDynamoDb(); - const params = { - TableName: tableName, - Item: marshall(row), - ReturnValues: 'ALL_OLD' as const, - }; - await documentClient.send(new PutItemCommand(params)); - const primaryKey = await this.getTablePrimaryColumns(tableName); - const responseObject = {}; - primaryKey.forEach((key) => { - responseObject[key.column_name] = row[key.column_name]; - }); - return responseObject; - } catch (e) { - e.message += '.'; - throw e; - } - } - - public async deleteRowInTable( - tableName: string, - primaryKey: Record, - ): Promise> { - try { - const tableStructure = await this.getTableStructure(tableName); - for (const key in primaryKey) { - const foundKeySchema = tableStructure.find((el) => el.column_name === key); - if (foundKeySchema?.data_type === 'number') { - const numericValue = Number(primaryKey[key]); - if (!Number.isNaN(numericValue)) { - primaryKey[key] = numericValue; - } else { - } - } - } - const { documentClient } = this.getDynamoDb(); - const params = { - TableName: tableName, - Key: marshall(primaryKey), - ReturnValues: 'ALL_OLD' as const, - }; - await documentClient.send(new DeleteItemCommand(params)); - return primaryKey; - } catch (e) { - e.message += '.'; - throw e; - } - } - - public async getIdentityColumns( - tableName: string, - referencedFieldName: string, - identityColumnName: string, - fieldValues: (string | number)[], - ): Promise[]> { - if (!referencedFieldName || !fieldValues.length) { - return []; - } - const { dynamoDb } = this.getDynamoDb(); - const expressionAttributeValues: { [key: string]: any } = {}; - const expressionAttributeNames: { [key: string]: string } = {}; - - fieldValues.forEach((value, index) => { - const valueKey = `:value${index}`; - expressionAttributeValues[valueKey] = typeof value === 'string' ? { S: value } : { N: value.toString() }; - }); - - expressionAttributeNames[`#referencedField`] = referencedFieldName; - - const filterExpression = `#referencedField IN (${Object.keys(expressionAttributeValues).join(', ')})`; - - let projectionExpression = `#referencedField`; - - if (identityColumnName) { - expressionAttributeNames[`#identityField`] = identityColumnName; - projectionExpression += `, #identityField`; - } - - const params = { - TableName: tableName, - FilterExpression: filterExpression, - ExpressionAttributeValues: expressionAttributeValues, - ExpressionAttributeNames: expressionAttributeNames, - ProjectionExpression: projectionExpression, - }; - - const result = await dynamoDb.scan(params); - const items = result.Items || []; - - const transformedResult = items.map((item) => - this.transformAndFilterRow(item, [identityColumnName, referencedFieldName].filter(Boolean), []), - ); - return transformedResult; - } - - public async getRowByPrimaryKey( - tableName: string, - primaryKey: Record, - settings: TableSettingsDS, - ): Promise> { - const tableStructure = await this.getTableStructure(tableName); - for (const key in primaryKey) { - const foundKeySchema = tableStructure.find((el) => el.column_name === key); - if (foundKeySchema?.data_type === 'number') { - const numericValue = Number(primaryKey[key]); - if (!Number.isNaN(numericValue)) { - primaryKey[key] = numericValue; - } else { - } - } - } - let availableFields: string[] = []; - if (settings) { - availableFields = this.findAvailableFields(settings, tableStructure); - } - - const { documentClient } = this.getDynamoDb(); - const params = { - TableName: tableName, - Key: marshall(primaryKey), - }; - const result = await documentClient.send(new GetItemCommand(params)); - - const foundRow = result.Item ? this.transformAndFilterRow(result.Item, availableFields, tableStructure) : null; - if (!foundRow) { - return null; - } - return foundRow; - } - - public async bulkGetRowsFromTableByPrimaryKeys( - tableName: string, - primaryKeys: Array>, - settings: TableSettingsDS, - ): Promise>> { - const { documentClient } = this.getDynamoDb(); - const tableStructure = await this.getTableStructure(tableName); - - const keys = primaryKeys.map((primaryKey) => { - const marshalledKey = {}; - for (const key in primaryKey) { - const schema = tableStructure.find((element) => element.column_name === key); - const value = schema?.data_type === 'number' ? Number(primaryKey[key]) : primaryKey[key]; - if (schema?.data_type === 'number' && Number.isNaN(value as number)) { - throw new Error(`Invalid number value for key: ${key}`); - } - marshalledKey[key] = value; - } - return marshall(marshalledKey); - }); - - let availableFields: string[] = []; - if (settings) { - availableFields = this.findAvailableFields(settings, tableStructure); - } - - const params = { - RequestItems: { - [tableName]: { - Keys: keys, - }, - }, - }; - - const result = await documentClient.send(new BatchGetItemCommand(params)); - - const items = result.Responses?.[tableName] || []; - return items.map((item) => this.transformAndFilterRow(item, availableFields, tableStructure)); - } - - public async getRowsFromTable( - tableName: string, - settings: TableSettingsDS, - page: number, - perPage: number, - searchedFieldValue: string, - filteringFields: FilteringFieldsDS[], - autocompleteFields: AutocompleteFieldsDS, - tableStructure: TableStructureDS[] | null, - ): Promise { - const { dynamoDb } = this.getDynamoDb(); - - page = page > 0 ? page : DAO_CONSTANTS.DEFAULT_PAGINATION.page; - perPage = - perPage > 0 - ? perPage - : settings.list_per_page > 0 - ? settings.list_per_page - : DAO_CONSTANTS.DEFAULT_PAGINATION.perPage; - - if (!tableStructure) { - tableStructure = await this.getTableStructure(tableName); - } - const availableFields = this.findAvailableFields(settings, tableStructure); - - let filterExpression = ''; - let expressionAttributeValues: { [key: string]: any } = {}; - const expressionAttributeNames: { [key: string]: string } = {}; - - if (autocompleteFields?.value && autocompleteFields.fields?.length > 0) { - const { fields, value } = autocompleteFields; - filterExpression = fields.map((field) => `#${field} = :value`).join(' OR '); - expressionAttributeValues = { ':value': { S: value } }; - fields.forEach((field) => { - expressionAttributeNames[`#${field}`] = field; - }); - - const params = { - TableName: tableName, - FilterExpression: filterExpression, - ExpressionAttributeValues: expressionAttributeValues, - ExpressionAttributeNames: expressionAttributeNames, - Limit: DAO_CONSTANTS.AUTOCOMPLETE_ROW_LIMIT, - }; - - const result = await dynamoDb.scan(params); - const rows = result.Items; - const large_dataset = rows.length >= DAO_CONSTANTS.AUTOCOMPLETE_ROW_LIMIT; - - return { - data: rows.map((row) => this.transformAndFilterRow(row, availableFields, tableStructure)), - large_dataset, - pagination: {} as any, - }; - } - - if (searchedFieldValue && settings.search_fields?.length > 0) { - const searchFields = settings.search_fields.length > 0 ? settings.search_fields : availableFields; - filterExpression = searchFields - .map((field) => { - const fieldInfo = tableStructure.find((el) => el.column_name === field); - const isNumberField = fieldInfo?.data_type === 'number'; - if (isNumberField) { - const numericValue = Number(searchedFieldValue); - if (!Number.isNaN(numericValue)) { - expressionAttributeValues[`:${field}_value`] = { N: String(numericValue) }; - return `#${field} = :${field}_value`; - } - return null; - } else { - expressionAttributeValues[`:${field}_value`] = { S: searchedFieldValue }; - return `contains(#${field}, :${field}_value)`; - } - }) - .filter((expression) => expression !== null) - .join(' OR '); - - searchFields.forEach((field) => { - expressionAttributeNames[`#${field}`] = field; - }); - } - - if (filteringFields?.length > 0) { - filteringFields.forEach((filter, index) => { - const { field, criteria, value } = filter; - expressionAttributeNames[`#${field}`] = field; - const uniquePlaceholder = `:${field}${index}`; - const fieldInfo = tableStructure.find((el) => el.column_name === field); - const isNumberField = fieldInfo?.data_type === 'number'; - - switch (criteria) { - case FilterCriteriaEnum.eq: - filterExpression += ` AND #${field} = ${uniquePlaceholder}`; - expressionAttributeValues[uniquePlaceholder] = isNumberField ? { N: String(value) } : { S: value }; - break; - case FilterCriteriaEnum.contains: - filterExpression += ` AND contains(#${field}, ${uniquePlaceholder})`; - expressionAttributeValues[uniquePlaceholder] = { S: value }; - break; - case FilterCriteriaEnum.gt: - filterExpression += ` AND #${field} > ${uniquePlaceholder}`; - expressionAttributeValues[uniquePlaceholder] = isNumberField ? { N: String(value) } : { S: value }; - break; - case FilterCriteriaEnum.lt: - filterExpression += ` AND #${field} < ${uniquePlaceholder}`; - expressionAttributeValues[uniquePlaceholder] = isNumberField ? { N: String(value) } : { S: value }; - break; - case FilterCriteriaEnum.gte: - filterExpression += ` AND #${field} >= ${uniquePlaceholder}`; - expressionAttributeValues[uniquePlaceholder] = isNumberField ? { N: String(value) } : { S: value }; - break; - case FilterCriteriaEnum.lte: - filterExpression += ` AND #${field} <= ${uniquePlaceholder}`; - expressionAttributeValues[uniquePlaceholder] = isNumberField ? { N: String(value) } : { S: value }; - break; - case FilterCriteriaEnum.icontains: - filterExpression += ` AND NOT contains(#${field}, ${uniquePlaceholder})`; - expressionAttributeValues[uniquePlaceholder] = { S: value }; - break; - case FilterCriteriaEnum.startswith: - filterExpression += ` AND begins_with(#${field}, ${uniquePlaceholder})`; - expressionAttributeValues[uniquePlaceholder] = { S: value }; - break; - case FilterCriteriaEnum.endswith: - filterExpression += ` AND ends_with(#${field}, ${uniquePlaceholder})`; - expressionAttributeValues[uniquePlaceholder] = { S: value }; - break; - case FilterCriteriaEnum.empty: - filterExpression += ` AND attribute_not_exists(#${field})`; - break; - default: - break; - } - if (index === 0) { - filterExpression = filterExpression.replace(/^ AND /, ''); - } - }); - } - - const totalRowsCount = await this.countTotalRows( - tableName, - filterExpression, - expressionAttributeValues, - expressionAttributeNames, - ); - - let lastEvaluatedKey = null; - let rows = []; - - do { - const params: any = { - TableName: tableName, - Limit: perPage, - ExclusiveStartKey: lastEvaluatedKey, - }; - - if (filterExpression) { - params.FilterExpression = filterExpression; - } - - if (Object.keys(expressionAttributeValues).length) { - params.ExpressionAttributeValues = expressionAttributeValues; - } - - if (Object.keys(expressionAttributeNames).length) { - params.ExpressionAttributeNames = expressionAttributeNames; - } - - const result = await dynamoDb.scan(params); - - rows = rows.concat(result.Items); - lastEvaluatedKey = result.LastEvaluatedKey; - } while (lastEvaluatedKey); - - if (settings.ordering_field && settings.ordering) { - rows = this.sortRows(rows, settings.ordering_field, settings.ordering); - } - - const itemsToSkip = (page - 1) * perPage; - rows = rows.slice(itemsToSkip, itemsToSkip + perPage); - - const large_dataset = totalRowsCount >= DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT; - - const pagination = { - total: totalRowsCount, - lastPage: Math.ceil(totalRowsCount / perPage), - perPage: perPage, - currentPage: page, - }; - - return { - data: rows.map((row) => this.transformAndFilterRow(row, availableFields, tableStructure)), - pagination, - large_dataset, - }; - } - - public async getTableForeignKeys(_tableName: string): Promise> { - return []; - } - - public async getTablePrimaryColumns(tableName: string): Promise> { - const { dynamoDb } = this.getDynamoDb(); - const params = { - TableName: tableName, - }; - const tableDescription = await dynamoDb.describeTable(params); - const keySchema = tableDescription.Table.KeySchema; - const attributeDefinitions = tableDescription.Table.AttributeDefinitions; - - const primaryKeys = keySchema.map((key) => { - const attributeDefinition = attributeDefinitions.find((attr) => attr.AttributeName === key.AttributeName); - return { - column_name: key.AttributeName, - data_type: this.convertTypeName(attributeDefinition.AttributeType), - }; - }); - return primaryKeys; - } - - public async getTablesFromDB(): Promise> { - const { dynamoDb } = this.getDynamoDb(); - const result = await dynamoDb.listTables(); - const tableNames = result.TableNames; - const tables = tableNames.map((tableName) => { - return { - tableName: tableName, - isView: false, - }; - }); - return tables; - } - - public async getTableStructure(tableName: string): Promise> { - return this.getTableStructureOrReturnPrimaryKeysIfNothingToScan(tableName); - } - - public async testConnect(): Promise { - const { dynamoDb } = this.getDynamoDb(); - try { - await dynamoDb.listTables(); - return { - result: true, - message: 'Successfully connected', - }; - } catch (error) { - return { - result: false, - message: error.message, - }; - } - } - - public async updateRowInTable( - tableName: string, - row: Record, - primaryKey: Record, - ): Promise> { - try { - const tableStructure = await this.getTableStructure(tableName); - row = this.convertHexDataToBinaryInBinarySets(row, tableStructure); - for (const key in primaryKey) { - const foundKeySchema = tableStructure.find((el) => el.column_name === key); - if (foundKeySchema?.data_type === 'number') { - const numericValue = Number(primaryKey[key]); - if (!Number.isNaN(numericValue)) { - primaryKey[key] = numericValue; - } else { - } - } - } - const { documentClient } = this.getDynamoDb(); - const params = { - TableName: tableName, - Key: marshall(primaryKey), - AttributeUpdates: Object.entries(row).reduce((acc, [key, value]) => { - acc[key] = { - Action: 'PUT', - Value: marshall({ [key]: value })[key], - }; - return acc; - }, {}), - ReturnValues: 'ALL_NEW' as const, - }; - await documentClient.send(new UpdateItemCommand(params)); - const primaryKeyColumns = await this.getTablePrimaryColumns(tableName); - const responseObject = {}; - primaryKeyColumns.forEach((key) => { - responseObject[key.column_name] = row[key.column_name]; - }); - - if (isObjectEmpty(responseObject)) { - return primaryKey; - } - return responseObject; - } catch (e) { - e.message += '.'; - throw e; - } - } - - public async bulkUpdateRowsInTable( - tableName: string, - newValues: Record, - primaryKeys: Array>, - ): Promise>> { - const { documentClient } = this.getDynamoDb(); - const structure = await this.getTableStructure(tableName); - newValues = this.convertHexDataToBinaryInBinarySets(newValues, structure); - const updatePromises = primaryKeys.map((primaryKey) => { - const updateExpression = - 'SET ' + - Object.keys(newValues) - .map((_key, index) => `#key${index} = :value${index}`) - .join(', '); - const expressionAttributeNames = Object.keys(newValues).reduce((acc, key, index) => { - acc[`#key${index}`] = key; - return acc; - }, {}); - const expressionAttributeValues = Object.keys(newValues).reduce((acc, key, index) => { - acc[`:value${index}`] = newValues[key]; - return acc; - }, {}); - - const params = { - TableName: tableName, - Key: marshall(primaryKey), - UpdateExpression: updateExpression, - ExpressionAttributeNames: expressionAttributeNames, - ExpressionAttributeValues: marshall(expressionAttributeValues), - ReturnValues: 'ALL_NEW' as const, - }; - - return documentClient.send(new UpdateItemCommand(params)); - }); - - await Promise.all(updatePromises); - return primaryKeys as any; - } - - public async bulkDeleteRowsInTable(tableName: string, primaryKeys: Array>): Promise { - const { documentClient } = this.getDynamoDb(); - - if (primaryKeys.length === 0) { - return 0; - } - - const tableStructure = await this.getTableStructure(tableName); - - const deletePromises = primaryKeys.map(async (primaryKey) => { - for (const key in primaryKey) { - const foundKeySchema = tableStructure.find((el) => el.column_name === key); - if (foundKeySchema?.data_type === 'number') { - const numericValue = Number(primaryKey[key]); - if (!Number.isNaN(numericValue)) { - primaryKey[key] = numericValue; - } - } - } - - try { - const params = { - TableName: tableName, - Key: marshall(primaryKey), - }; - await documentClient.send(new DeleteItemCommand(params)); - } catch (e) { - console.error(`Failed to delete item with key ${JSON.stringify(primaryKey)}: ${e.message}`); - } - }); - - await Promise.all(deletePromises); - return primaryKeys.length; - } - - public async validateSettings(settings: ValidateTableSettingsDS, tableName: string): Promise> { - const [tableStructure, primaryColumns] = await Promise.all([ - this.getTableStructure(tableName), - this.getTablePrimaryColumns(tableName), - ]); - return tableSettingsFieldValidator(tableStructure, primaryColumns, settings); - } - - public async getReferencedTableNamesAndColumns(_tableName: string): Promise> { - return []; - } - - public async isView(_tableName: string): Promise { - return false; - } - - public async getTableRowsStream( - tableName: string, - settings: TableSettingsDS, - page: number, - perPage: number, - searchedFieldValue: string, - filteringFields: Array, - ): Promise> { - const result = await this.getRowsFromTable( - tableName, - settings, - page, - perPage, - searchedFieldValue, - filteringFields, - null, - null, - ); - return result.data as any; - } - - public async importCSVInTable(file: Express.Multer.File, tableName: string): Promise { - const fileStream = new Stream.PassThrough(); - fileStream.end(file.buffer); - - return new Promise((resolve, reject) => { - fileStream - .pipe(csv.parse({ columns: true })) - .on('data', async (data) => { - try { - await this.addRowInTable(tableName, data); - } catch (err) { - reject(err); - } - }) - .on('end', () => { - resolve(); - }) - .on('error', (err) => { - reject(err); - }); - }); - } - - public async executeRawQuery(_query: string): Promise>> { - throw new Error('Method not implemented.'); - } - - private convertHexDataToBinaryInBinarySets( - row: Record, - tableStructure: Array, - ): Record { - const binarySetColumns = tableStructure - .map((el) => { - return { - column_name: el.column_name, - data_type: el.data_type, - dynamo_db_type: el.dynamo_db_type, - }; - }) - .filter((el) => { - return el?.dynamo_db_type === 'BS'; - }); - - if (binarySetColumns.length) { - for (const column of binarySetColumns) { - if (row[column.column_name] && Array.isArray(row[column.column_name])) { - try { - row[column.column_name] = (row[column.column_name] as string[]).map((value) => hexToBinary(value)); - } catch (_e) { - } - } - } - } - return row; - } - - private getDynamoDb(): DdAndClient { - const endpoint = this.connection.host; - const accessKeyId = this.connection.username; - const secretAccessKey = this.connection.password; - const regionMatch = endpoint.match(/dynamodb\.(.+?)\.amazonaws\.com/); - const region = regionMatch ? regionMatch[1] : 'us-east-1'; - const dynamoDb = new DynamoDB({ - endpoint: endpoint, - region: process.env.NODE_ENV === 'test' ? 'localhost' : region, - credentials: { - accessKeyId: accessKeyId, - secretAccessKey: secretAccessKey, - }, - }); - const documentClient = DynamoDBDocumentClient.from(dynamoDb); - return { dynamoDb, documentClient }; - } - - private convertTypeName(dynamoDbType: string): string { - switch (dynamoDbType) { - case 'S': - return 'string'; - case 'N': - return 'number'; - case 'B': - return 'binary'; - case 'HASH': - return 'string'; - case 'BOOL': - return 'boolean'; - case 'L': - return 'array'; - case 'M': - return 'json'; - case 'SS': - return 'array'; - case 'NS': - return 'array'; - case 'BS': - return 'array'; - case 'NULL': - return 'null'; - default: - return 'string'; - } - } - - private transformAndFilterRow( - row: { [key: string]: { [type: string]: any } }, - availableFields: string[], - tableStructure: Array, - ): { [key: string]: any } { - const transformedRow: { [key: string]: any } = {}; - - Object.keys(row).forEach((key) => { - const attribute = row[key]; - const attributeType = Object.keys(attribute)[0]; - transformedRow[key] = attribute[attributeType]; - const fieldInfo = tableStructure.find((el) => el.column_name === key); - if (fieldInfo?.data_type === 'number' || attributeType === 'N') { - const valueToNumber = Number(transformedRow[key]); - if (!Number.isNaN(valueToNumber)) { - transformedRow[key] = valueToNumber; - } - } - if (fieldInfo?.dynamo_db_type === 'BS' || attributeType === 'BS') { - const valuesArray = transformedRow[key]; - if (valuesArray && Array.isArray(valuesArray)) { - transformedRow[key] = valuesArray.map((value) => binaryToHex(value)); - } - } - - if (fieldInfo?.dynamo_db_type === 'L' || attributeType === 'L') { - const valuesArray = transformedRow[key]; - if (valuesArray && Array.isArray(valuesArray)) { - transformedRow[key] = valuesArray.map((value) => Object.values(value)[0]); - } - } - - if (fieldInfo?.dynamo_db_type === 'NULL' || attributeType === 'NULL') { - transformedRow[key] = null; - } - }); - - if (availableFields.length > 0) { - Object.keys(transformedRow).forEach((key) => { - if (!availableFields.includes(key)) { - delete transformedRow[key]; - } - }); - } - - return transformedRow; - } - - private async countTotalRows( - tableName: string, - filterExpression: string, - expressionAttributeValues: { [key: string]: any }, - expressionAttributeNames: { [key: string]: string }, - ): Promise { - let lastEvaluatedKey = null; - let totalRowsCount = 0; - const { dynamoDb } = this.getDynamoDb(); - do { - const params: any = { - TableName: tableName, - ExclusiveStartKey: lastEvaluatedKey, - }; - - if (filterExpression) { - params.FilterExpression = filterExpression; - } - - if (filterExpression && Object.keys(expressionAttributeValues).length) { - params.ExpressionAttributeValues = expressionAttributeValues; - } - - if (filterExpression && Object.keys(expressionAttributeNames).length) { - params.ExpressionAttributeNames = expressionAttributeNames; - } - - const result = await dynamoDb.scan(params); - totalRowsCount += result.Count; - lastEvaluatedKey = result.LastEvaluatedKey; - } while (lastEvaluatedKey); - - return totalRowsCount; - } - - private sortRows(rows: any[], orderingField: string, ordering: QueryOrderingEnum): any[] { - return rows.sort((a, b) => { - const aValue = a[orderingField]?.S || a[orderingField]?.N || ''; - const bValue = b[orderingField]?.S || b[orderingField]?.N || ''; - - if (ordering === QueryOrderingEnum.ASC) { - return aValue > bValue ? 1 : aValue < bValue ? -1 : 0; - } else { - return aValue < bValue ? 1 : aValue > bValue ? -1 : 0; - } - }); - } - - private async getTableStructureOrReturnPrimaryKeysIfNothingToScan( - tableName: string, - ): Promise> { - try { - const { dynamoDb } = this.getDynamoDb(); - const documentClient = DynamoDBDocumentClient.from(dynamoDb); - - const params = { - TableName: tableName, - Limit: 100, - }; - - const scanResult = await documentClient.send(new ScanCommand(params)); - const items = scanResult.Items || []; - - const attributeTypes: { [key: string]: string } = {}; - - items.forEach((item) => { - Object.keys(item).forEach((key) => { - if (!attributeTypes[key]) { - const attributeValue = item[key]; - const attributeType = Object.keys(attributeValue)[0]; - attributeTypes[key] = attributeType; - } - }); - }); - - const tableStructure: Array = Object.keys(attributeTypes).map((attributeName) => { - return { - allow_null: true, - character_maximum_length: null, - column_default: null, - column_name: attributeName, - data_type: this.convertTypeName(attributeTypes[attributeName]), - data_type_params: null, - udt_name: null, - extra: null, - dynamo_db_type: (attributeTypes[attributeName] as DynamoDBType) ?? null, - }; - }); - - if (!tableStructure.length) { - const primaryKeys = await this.getTablePrimaryColumns(tableName); - return primaryKeys.map((key) => { - return { - allow_null: false, - character_maximum_length: null, - column_default: null, - column_name: key.column_name, - data_type: key.data_type, - data_type_params: null, - udt_name: null, - extra: null, - }; - }); - } - - return tableStructure; - } catch (error) { - console.error(error); - throw error; - } - } + public async addRowInTable( + tableName: string, + row: Record, + ): Promise | number> { + try { + const tableStructure = await this.getTableStructure(tableName); + row = this.convertHexDataToBinaryInBinarySets(row, tableStructure); + const { documentClient } = this.getDynamoDb(); + const params = { + TableName: tableName, + Item: marshall(row), + ReturnValues: 'ALL_OLD' as const, + }; + await documentClient.send(new PutItemCommand(params)); + const primaryKey = await this.getTablePrimaryColumns(tableName); + const responseObject = {}; + primaryKey.forEach((key) => { + responseObject[key.column_name] = row[key.column_name]; + }); + return responseObject; + } catch (e) { + e.message += '.'; + throw e; + } + } + + public async deleteRowInTable( + tableName: string, + primaryKey: Record, + ): Promise> { + try { + const tableStructure = await this.getTableStructure(tableName); + for (const key in primaryKey) { + const foundKeySchema = tableStructure.find((el) => el.column_name === key); + if (foundKeySchema?.data_type === 'number') { + const numericValue = Number(primaryKey[key]); + if (!Number.isNaN(numericValue)) { + primaryKey[key] = numericValue; + } else { + } + } + } + const { documentClient } = this.getDynamoDb(); + const params = { + TableName: tableName, + Key: marshall(primaryKey), + ReturnValues: 'ALL_OLD' as const, + }; + await documentClient.send(new DeleteItemCommand(params)); + return primaryKey; + } catch (e) { + e.message += '.'; + throw e; + } + } + + public async getIdentityColumns( + tableName: string, + referencedFieldName: string, + identityColumnName: string, + fieldValues: (string | number)[], + ): Promise[]> { + if (!referencedFieldName || !fieldValues.length) { + return []; + } + const { dynamoDb } = this.getDynamoDb(); + const expressionAttributeValues: { [key: string]: any } = {}; + const expressionAttributeNames: { [key: string]: string } = {}; + + fieldValues.forEach((value, index) => { + const valueKey = `:value${index}`; + expressionAttributeValues[valueKey] = typeof value === 'string' ? { S: value } : { N: value.toString() }; + }); + + expressionAttributeNames[`#referencedField`] = referencedFieldName; + + const filterExpression = `#referencedField IN (${Object.keys(expressionAttributeValues).join(', ')})`; + + let projectionExpression = `#referencedField`; + + if (identityColumnName) { + expressionAttributeNames[`#identityField`] = identityColumnName; + projectionExpression += `, #identityField`; + } + + const params = { + TableName: tableName, + FilterExpression: filterExpression, + ExpressionAttributeValues: expressionAttributeValues, + ExpressionAttributeNames: expressionAttributeNames, + ProjectionExpression: projectionExpression, + }; + + const result = await dynamoDb.scan(params); + const items = result.Items || []; + + const transformedResult = items.map((item) => + this.transformAndFilterRow(item, [identityColumnName, referencedFieldName].filter(Boolean), []), + ); + return transformedResult; + } + + public async getRowByPrimaryKey( + tableName: string, + primaryKey: Record, + settings: TableSettingsDS, + ): Promise> { + const tableStructure = await this.getTableStructure(tableName); + for (const key in primaryKey) { + const foundKeySchema = tableStructure.find((el) => el.column_name === key); + if (foundKeySchema?.data_type === 'number') { + const numericValue = Number(primaryKey[key]); + if (!Number.isNaN(numericValue)) { + primaryKey[key] = numericValue; + } else { + } + } + } + let availableFields: string[] = []; + if (settings) { + availableFields = this.findAvailableFields(settings, tableStructure); + } + + const { documentClient } = this.getDynamoDb(); + const params = { + TableName: tableName, + Key: marshall(primaryKey), + }; + const result = await documentClient.send(new GetItemCommand(params)); + + const foundRow = result.Item ? this.transformAndFilterRow(result.Item, availableFields, tableStructure) : null; + if (!foundRow) { + return null; + } + return foundRow; + } + + public async bulkGetRowsFromTableByPrimaryKeys( + tableName: string, + primaryKeys: Array>, + settings: TableSettingsDS, + ): Promise>> { + const { documentClient } = this.getDynamoDb(); + const tableStructure = await this.getTableStructure(tableName); + + const keys = primaryKeys.map((primaryKey) => { + const marshalledKey = {}; + for (const key in primaryKey) { + const schema = tableStructure.find((element) => element.column_name === key); + const value = schema?.data_type === 'number' ? Number(primaryKey[key]) : primaryKey[key]; + if (schema?.data_type === 'number' && Number.isNaN(value as number)) { + throw new Error(`Invalid number value for key: ${key}`); + } + marshalledKey[key] = value; + } + return marshall(marshalledKey); + }); + + let availableFields: string[] = []; + if (settings) { + availableFields = this.findAvailableFields(settings, tableStructure); + } + + const params = { + RequestItems: { + [tableName]: { + Keys: keys, + }, + }, + }; + + const result = await documentClient.send(new BatchGetItemCommand(params)); + + const items = result.Responses?.[tableName] || []; + return items.map((item) => this.transformAndFilterRow(item, availableFields, tableStructure)); + } + + public async getRowsFromTable( + tableName: string, + settings: TableSettingsDS, + page: number, + perPage: number, + searchedFieldValue: string, + filteringFields: FilteringFieldsDS[], + autocompleteFields: AutocompleteFieldsDS, + tableStructure: TableStructureDS[] | null, + ): Promise { + const { dynamoDb } = this.getDynamoDb(); + + page = page > 0 ? page : DAO_CONSTANTS.DEFAULT_PAGINATION.page; + perPage = + perPage > 0 + ? perPage + : settings.list_per_page > 0 + ? settings.list_per_page + : DAO_CONSTANTS.DEFAULT_PAGINATION.perPage; + + if (!tableStructure) { + tableStructure = await this.getTableStructure(tableName); + } + const availableFields = this.findAvailableFields(settings, tableStructure); + + let filterExpression = ''; + let expressionAttributeValues: { [key: string]: any } = {}; + const expressionAttributeNames: { [key: string]: string } = {}; + + if (autocompleteFields?.value && autocompleteFields.fields?.length > 0) { + const { fields, value } = autocompleteFields; + filterExpression = fields.map((field) => `#${field} = :value`).join(' OR '); + expressionAttributeValues = { ':value': { S: value } }; + fields.forEach((field) => { + expressionAttributeNames[`#${field}`] = field; + }); + + const params = { + TableName: tableName, + FilterExpression: filterExpression, + ExpressionAttributeValues: expressionAttributeValues, + ExpressionAttributeNames: expressionAttributeNames, + Limit: DAO_CONSTANTS.AUTOCOMPLETE_ROW_LIMIT, + }; + + const result = await dynamoDb.scan(params); + const rows = result.Items; + const large_dataset = rows.length >= DAO_CONSTANTS.AUTOCOMPLETE_ROW_LIMIT; + + return { + data: rows.map((row) => this.transformAndFilterRow(row, availableFields, tableStructure)), + large_dataset, + pagination: {} as any, + }; + } + + if (searchedFieldValue && settings.search_fields?.length > 0) { + const searchFields = settings.search_fields.length > 0 ? settings.search_fields : availableFields; + filterExpression = searchFields + .map((field) => { + const fieldInfo = tableStructure.find((el) => el.column_name === field); + const isNumberField = fieldInfo?.data_type === 'number'; + if (isNumberField) { + const numericValue = Number(searchedFieldValue); + if (!Number.isNaN(numericValue)) { + expressionAttributeValues[`:${field}_value`] = { N: String(numericValue) }; + return `#${field} = :${field}_value`; + } + return null; + } else { + expressionAttributeValues[`:${field}_value`] = { S: searchedFieldValue }; + return `contains(#${field}, :${field}_value)`; + } + }) + .filter((expression) => expression !== null) + .join(' OR '); + + searchFields.forEach((field) => { + expressionAttributeNames[`#${field}`] = field; + }); + } + + if (filteringFields?.length > 0) { + filteringFields.forEach((filter, index) => { + const { field, criteria, value } = filter; + expressionAttributeNames[`#${field}`] = field; + const uniquePlaceholder = `:${field}${index}`; + const fieldInfo = tableStructure.find((el) => el.column_name === field); + const isNumberField = fieldInfo?.data_type === 'number'; + + switch (criteria) { + case FilterCriteriaEnum.eq: + filterExpression += ` AND #${field} = ${uniquePlaceholder}`; + expressionAttributeValues[uniquePlaceholder] = isNumberField ? { N: String(value) } : { S: value }; + break; + case FilterCriteriaEnum.contains: + filterExpression += ` AND contains(#${field}, ${uniquePlaceholder})`; + expressionAttributeValues[uniquePlaceholder] = { S: value }; + break; + case FilterCriteriaEnum.gt: + filterExpression += ` AND #${field} > ${uniquePlaceholder}`; + expressionAttributeValues[uniquePlaceholder] = isNumberField ? { N: String(value) } : { S: value }; + break; + case FilterCriteriaEnum.lt: + filterExpression += ` AND #${field} < ${uniquePlaceholder}`; + expressionAttributeValues[uniquePlaceholder] = isNumberField ? { N: String(value) } : { S: value }; + break; + case FilterCriteriaEnum.gte: + filterExpression += ` AND #${field} >= ${uniquePlaceholder}`; + expressionAttributeValues[uniquePlaceholder] = isNumberField ? { N: String(value) } : { S: value }; + break; + case FilterCriteriaEnum.lte: + filterExpression += ` AND #${field} <= ${uniquePlaceholder}`; + expressionAttributeValues[uniquePlaceholder] = isNumberField ? { N: String(value) } : { S: value }; + break; + case FilterCriteriaEnum.icontains: + filterExpression += ` AND NOT contains(#${field}, ${uniquePlaceholder})`; + expressionAttributeValues[uniquePlaceholder] = { S: value }; + break; + case FilterCriteriaEnum.startswith: + filterExpression += ` AND begins_with(#${field}, ${uniquePlaceholder})`; + expressionAttributeValues[uniquePlaceholder] = { S: value }; + break; + case FilterCriteriaEnum.endswith: + filterExpression += ` AND ends_with(#${field}, ${uniquePlaceholder})`; + expressionAttributeValues[uniquePlaceholder] = { S: value }; + break; + case FilterCriteriaEnum.empty: + filterExpression += ` AND attribute_not_exists(#${field})`; + break; + default: + break; + } + if (index === 0) { + filterExpression = filterExpression.replace(/^ AND /, ''); + } + }); + } + + const totalRowsCount = await this.countTotalRows( + tableName, + filterExpression, + expressionAttributeValues, + expressionAttributeNames, + ); + + let lastEvaluatedKey = null; + let rows = []; + + do { + const params: any = { + TableName: tableName, + Limit: perPage, + ExclusiveStartKey: lastEvaluatedKey, + }; + + if (filterExpression) { + params.FilterExpression = filterExpression; + } + + if (Object.keys(expressionAttributeValues).length) { + params.ExpressionAttributeValues = expressionAttributeValues; + } + + if (Object.keys(expressionAttributeNames).length) { + params.ExpressionAttributeNames = expressionAttributeNames; + } + + const result = await dynamoDb.scan(params); + + rows = rows.concat(result.Items); + lastEvaluatedKey = result.LastEvaluatedKey; + } while (lastEvaluatedKey); + + if (settings.ordering_field && settings.ordering) { + rows = this.sortRows(rows, settings.ordering_field, settings.ordering); + } + + const itemsToSkip = (page - 1) * perPage; + rows = rows.slice(itemsToSkip, itemsToSkip + perPage); + + const large_dataset = totalRowsCount >= DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT; + + const pagination = { + total: totalRowsCount, + lastPage: Math.ceil(totalRowsCount / perPage), + perPage: perPage, + currentPage: page, + }; + + return { + data: rows.map((row) => this.transformAndFilterRow(row, availableFields, tableStructure)), + pagination, + large_dataset, + }; + } + + public async getTableForeignKeys(_tableName: string): Promise> { + return []; + } + + public async getTablePrimaryColumns(tableName: string): Promise> { + const { dynamoDb } = this.getDynamoDb(); + const params = { + TableName: tableName, + }; + const tableDescription = await dynamoDb.describeTable(params); + const keySchema = tableDescription.Table.KeySchema; + const attributeDefinitions = tableDescription.Table.AttributeDefinitions; + + const primaryKeys = keySchema.map((key) => { + const attributeDefinition = attributeDefinitions.find((attr) => attr.AttributeName === key.AttributeName); + return { + column_name: key.AttributeName, + data_type: this.convertTypeName(attributeDefinition.AttributeType), + }; + }); + return primaryKeys; + } + + public async getTablesFromDB(): Promise> { + const { dynamoDb } = this.getDynamoDb(); + const result = await dynamoDb.listTables(); + const tableNames = result.TableNames; + const tables = tableNames.map((tableName) => { + return { + tableName: tableName, + isView: false, + }; + }); + return tables; + } + + public async getTableStructure(tableName: string): Promise> { + return this.getTableStructureOrReturnPrimaryKeysIfNothingToScan(tableName); + } + + public async testConnect(): Promise { + const { dynamoDb } = this.getDynamoDb(); + try { + await dynamoDb.listTables(); + return { + result: true, + message: 'Successfully connected', + }; + } catch (error) { + return { + result: false, + message: error.message, + }; + } + } + + public async updateRowInTable( + tableName: string, + row: Record, + primaryKey: Record, + ): Promise> { + try { + const tableStructure = await this.getTableStructure(tableName); + row = this.convertHexDataToBinaryInBinarySets(row, tableStructure); + for (const key in primaryKey) { + const foundKeySchema = tableStructure.find((el) => el.column_name === key); + if (foundKeySchema?.data_type === 'number') { + const numericValue = Number(primaryKey[key]); + if (!Number.isNaN(numericValue)) { + primaryKey[key] = numericValue; + } else { + } + } + } + const { documentClient } = this.getDynamoDb(); + const params = { + TableName: tableName, + Key: marshall(primaryKey), + AttributeUpdates: Object.entries(row).reduce((acc, [key, value]) => { + acc[key] = { + Action: 'PUT', + Value: marshall({ [key]: value })[key], + }; + return acc; + }, {}), + ReturnValues: 'ALL_NEW' as const, + }; + await documentClient.send(new UpdateItemCommand(params)); + const primaryKeyColumns = await this.getTablePrimaryColumns(tableName); + const responseObject = {}; + primaryKeyColumns.forEach((key) => { + responseObject[key.column_name] = row[key.column_name]; + }); + + if (isObjectEmpty(responseObject)) { + return primaryKey; + } + return responseObject; + } catch (e) { + e.message += '.'; + throw e; + } + } + + public async bulkUpdateRowsInTable( + tableName: string, + newValues: Record, + primaryKeys: Array>, + ): Promise>> { + const { documentClient } = this.getDynamoDb(); + const structure = await this.getTableStructure(tableName); + newValues = this.convertHexDataToBinaryInBinarySets(newValues, structure); + const updatePromises = primaryKeys.map((primaryKey) => { + const updateExpression = + 'SET ' + + Object.keys(newValues) + .map((_key, index) => `#key${index} = :value${index}`) + .join(', '); + const expressionAttributeNames = Object.keys(newValues).reduce((acc, key, index) => { + acc[`#key${index}`] = key; + return acc; + }, {}); + const expressionAttributeValues = Object.keys(newValues).reduce((acc, key, index) => { + acc[`:value${index}`] = newValues[key]; + return acc; + }, {}); + + const params = { + TableName: tableName, + Key: marshall(primaryKey), + UpdateExpression: updateExpression, + ExpressionAttributeNames: expressionAttributeNames, + ExpressionAttributeValues: marshall(expressionAttributeValues), + ReturnValues: 'ALL_NEW' as const, + }; + + return documentClient.send(new UpdateItemCommand(params)); + }); + + await Promise.all(updatePromises); + return primaryKeys as any; + } + + public async bulkDeleteRowsInTable(tableName: string, primaryKeys: Array>): Promise { + const { documentClient } = this.getDynamoDb(); + + if (primaryKeys.length === 0) { + return 0; + } + + const tableStructure = await this.getTableStructure(tableName); + + const deletePromises = primaryKeys.map(async (primaryKey) => { + for (const key in primaryKey) { + const foundKeySchema = tableStructure.find((el) => el.column_name === key); + if (foundKeySchema?.data_type === 'number') { + const numericValue = Number(primaryKey[key]); + if (!Number.isNaN(numericValue)) { + primaryKey[key] = numericValue; + } + } + } + + try { + const params = { + TableName: tableName, + Key: marshall(primaryKey), + }; + await documentClient.send(new DeleteItemCommand(params)); + } catch (e) { + console.error(`Failed to delete item with key ${JSON.stringify(primaryKey)}: ${e.message}`); + } + }); + + await Promise.all(deletePromises); + return primaryKeys.length; + } + + public async validateSettings(settings: ValidateTableSettingsDS, tableName: string): Promise> { + const [tableStructure, primaryColumns] = await Promise.all([ + this.getTableStructure(tableName), + this.getTablePrimaryColumns(tableName), + ]); + return tableSettingsFieldValidator(tableStructure, primaryColumns, settings); + } + + public async getReferencedTableNamesAndColumns(_tableName: string): Promise> { + return []; + } + + public async isView(_tableName: string): Promise { + return false; + } + + public async getTableRowsStream( + tableName: string, + settings: TableSettingsDS, + page: number, + perPage: number, + searchedFieldValue: string, + filteringFields: Array, + ): Promise> { + const result = await this.getRowsFromTable( + tableName, + settings, + page, + perPage, + searchedFieldValue, + filteringFields, + null, + null, + ); + return result.data as any; + } + + public async importCSVInTable(file: Express.Multer.File, tableName: string): Promise { + const fileStream = new Stream.PassThrough(); + fileStream.end(file.buffer); + + return new Promise((resolve, reject) => { + fileStream + .pipe(csv.parse({ columns: true })) + .on('data', async (data) => { + try { + await this.addRowInTable(tableName, data); + } catch (err) { + reject(err); + } + }) + .on('end', () => { + resolve(); + }) + .on('error', (err) => { + reject(err); + }); + }); + } + + public async executeRawQuery(_query: string): Promise>> { + throw new Error('Method not implemented.'); + } + + private convertHexDataToBinaryInBinarySets( + row: Record, + tableStructure: Array, + ): Record { + const binarySetColumns = tableStructure + .map((el) => { + return { + column_name: el.column_name, + data_type: el.data_type, + dynamo_db_type: el.dynamo_db_type, + }; + }) + .filter((el) => { + return el?.dynamo_db_type === 'BS'; + }); + + if (binarySetColumns.length) { + for (const column of binarySetColumns) { + if (row[column.column_name] && Array.isArray(row[column.column_name])) { + try { + row[column.column_name] = (row[column.column_name] as string[]).map((value) => hexToBinary(value)); + } catch (_e) {} + } + } + } + return row; + } + + private getDynamoDb(): DdAndClient { + const endpoint = this.connection.host; + const accessKeyId = this.connection.username; + const secretAccessKey = this.connection.password; + const regionMatch = endpoint.match(/dynamodb\.(.+?)\.amazonaws\.com/); + const region = regionMatch ? regionMatch[1] : 'us-east-1'; + const dynamoDb = new DynamoDB({ + endpoint: endpoint, + region: process.env.NODE_ENV === 'test' ? 'localhost' : region, + credentials: { + accessKeyId: accessKeyId, + secretAccessKey: secretAccessKey, + }, + }); + const documentClient = DynamoDBDocumentClient.from(dynamoDb); + return { dynamoDb, documentClient }; + } + + private convertTypeName(dynamoDbType: string): string { + switch (dynamoDbType) { + case 'S': + return 'string'; + case 'N': + return 'number'; + case 'B': + return 'binary'; + case 'HASH': + return 'string'; + case 'BOOL': + return 'boolean'; + case 'L': + return 'array'; + case 'M': + return 'json'; + case 'SS': + return 'array'; + case 'NS': + return 'array'; + case 'BS': + return 'array'; + case 'NULL': + return 'null'; + default: + return 'string'; + } + } + + private transformAndFilterRow( + row: { [key: string]: { [type: string]: any } }, + availableFields: string[], + tableStructure: Array, + ): { [key: string]: any } { + const transformedRow: { [key: string]: any } = {}; + + Object.keys(row).forEach((key) => { + const attribute = row[key]; + const attributeType = Object.keys(attribute)[0]; + transformedRow[key] = attribute[attributeType]; + const fieldInfo = tableStructure.find((el) => el.column_name === key); + if (fieldInfo?.data_type === 'number' || attributeType === 'N') { + const valueToNumber = Number(transformedRow[key]); + if (!Number.isNaN(valueToNumber)) { + transformedRow[key] = valueToNumber; + } + } + if (fieldInfo?.dynamo_db_type === 'BS' || attributeType === 'BS') { + const valuesArray = transformedRow[key]; + if (valuesArray && Array.isArray(valuesArray)) { + transformedRow[key] = valuesArray.map((value) => binaryToHex(value)); + } + } + + if (fieldInfo?.dynamo_db_type === 'L' || attributeType === 'L') { + const valuesArray = transformedRow[key]; + if (valuesArray && Array.isArray(valuesArray)) { + transformedRow[key] = valuesArray.map((value) => Object.values(value)[0]); + } + } + + if (fieldInfo?.dynamo_db_type === 'NULL' || attributeType === 'NULL') { + transformedRow[key] = null; + } + }); + + if (availableFields.length > 0) { + Object.keys(transformedRow).forEach((key) => { + if (!availableFields.includes(key)) { + delete transformedRow[key]; + } + }); + } + + return transformedRow; + } + + private async countTotalRows( + tableName: string, + filterExpression: string, + expressionAttributeValues: { [key: string]: any }, + expressionAttributeNames: { [key: string]: string }, + ): Promise { + let lastEvaluatedKey = null; + let totalRowsCount = 0; + const { dynamoDb } = this.getDynamoDb(); + do { + const params: any = { + TableName: tableName, + ExclusiveStartKey: lastEvaluatedKey, + }; + + if (filterExpression) { + params.FilterExpression = filterExpression; + } + + if (filterExpression && Object.keys(expressionAttributeValues).length) { + params.ExpressionAttributeValues = expressionAttributeValues; + } + + if (filterExpression && Object.keys(expressionAttributeNames).length) { + params.ExpressionAttributeNames = expressionAttributeNames; + } + + const result = await dynamoDb.scan(params); + totalRowsCount += result.Count; + lastEvaluatedKey = result.LastEvaluatedKey; + } while (lastEvaluatedKey); + + return totalRowsCount; + } + + private sortRows(rows: any[], orderingField: string, ordering: QueryOrderingEnum): any[] { + return rows.sort((a, b) => { + const aValue = a[orderingField]?.S || a[orderingField]?.N || ''; + const bValue = b[orderingField]?.S || b[orderingField]?.N || ''; + + if (ordering === QueryOrderingEnum.ASC) { + return aValue > bValue ? 1 : aValue < bValue ? -1 : 0; + } else { + return aValue < bValue ? 1 : aValue > bValue ? -1 : 0; + } + }); + } + + private async getTableStructureOrReturnPrimaryKeysIfNothingToScan( + tableName: string, + ): Promise> { + try { + const { dynamoDb } = this.getDynamoDb(); + const documentClient = DynamoDBDocumentClient.from(dynamoDb); + + const params = { + TableName: tableName, + Limit: 100, + }; + + const scanResult = await documentClient.send(new ScanCommand(params)); + const items = scanResult.Items || []; + + const attributeTypes: { [key: string]: string } = {}; + + items.forEach((item) => { + Object.keys(item).forEach((key) => { + if (!attributeTypes[key]) { + const attributeValue = item[key]; + const attributeType = Object.keys(attributeValue)[0]; + attributeTypes[key] = attributeType; + } + }); + }); + + const tableStructure: Array = Object.keys(attributeTypes).map((attributeName) => { + return { + allow_null: true, + character_maximum_length: null, + column_default: null, + column_name: attributeName, + data_type: this.convertTypeName(attributeTypes[attributeName]), + data_type_params: null, + udt_name: null, + extra: null, + dynamo_db_type: (attributeTypes[attributeName] as DynamoDBType) ?? null, + }; + }); + + if (!tableStructure.length) { + const primaryKeys = await this.getTablePrimaryColumns(tableName); + return primaryKeys.map((key) => { + return { + allow_null: false, + character_maximum_length: null, + column_default: null, + column_name: key.column_name, + data_type: key.data_type, + data_type_params: null, + udt_name: null, + extra: null, + }; + }); + } + + return tableStructure; + } catch (error) { + console.error(error); + throw error; + } + } } diff --git a/shared-code/src/data-access-layer/data-access-objects/data-access-object-elasticsearch.ts b/shared-code/src/data-access-layer/data-access-objects/data-access-object-elasticsearch.ts index 6920e4b6b..501cfa8c5 100644 --- a/shared-code/src/data-access-layer/data-access-objects/data-access-object-elasticsearch.ts +++ b/shared-code/src/data-access-layer/data-access-objects/data-access-object-elasticsearch.ts @@ -20,669 +20,668 @@ import { IDataAccessObject } from '../../shared/interfaces/data-access-object.in import { BasicDataAccessObject } from './basic-data-access-object.js'; export class DataAccessObjectElasticsearch extends BasicDataAccessObject implements IDataAccessObject { - - public async addRowInTable( - tableName: string, - row: Record, - ): Promise | number> { - const client = this.getElasticClient(); - const response = await client.index({ - index: tableName, - document: row, - }); - await client.indices.refresh({ index: tableName }); - return { _id: response._id, ...row }; - } - - public async deleteRowInTable( - tableName: string, - primaryKey: Record, - ): Promise> { - const client = this.getElasticClient(); - const response = await client.delete({ - index: tableName, - id: primaryKey._id as string, - }); - if (response.result !== 'deleted') { - throw new Error('Document was not deleted successfully'); - } - await client.indices.refresh({ index: tableName }); - return { _id: primaryKey._id }; - } - - public async getIdentityColumns( - tableName: string, - referencedFieldName: string, - identityColumnName: string, - fieldValues: Array, - ): Promise>> { - const client = this.getElasticClient(); - const query = { - index: tableName, - body: { - query: { - terms: { - [referencedFieldName]: fieldValues, - }, - }, - _source: { - includes: identityColumnName ? [referencedFieldName, identityColumnName] : [referencedFieldName], - }, - }, - } as const; - - const response = await client.search(query as any); - - return response.hits.hits.map((hit) => { - const source = hit._source as Record; - return { - ...source, - _id: hit._id, - }; - }); - } - - public async getRowByPrimaryKey( - tableName: string, - primaryKey: Record, - settings: TableSettingsDS, - ): Promise> { - const primaryKeyValue = primaryKey._id; - const client = this.getElasticClient(); - let responseObject = {} as Record; - try { - const response = await client.get({ - index: tableName, - id: primaryKeyValue as string, - }); - responseObject = { - ...(response._source as Record), - _id: response._id, - }; - } catch (error) { - if (error.meta?.body?.found === false) { - return null; - } - throw error; - } - - let availableFields: string[] = []; - if (settings) { - const tableStructure = await this.getTableStructure(tableName); - availableFields = this.findAvailableFields(settings, tableStructure); - } - - if (availableFields.length > 0) { - Object.keys(responseObject).forEach((key) => { - if (!availableFields.includes(key)) { - // eslint-disable-next-line security/detect-object-injection - delete responseObject[key]; - } - }); - } - - return responseObject; - } - - public async bulkGetRowsFromTableByPrimaryKeys( - tableName: string, - primaryKeys: Array>, - settings: TableSettingsDS, - ): Promise>> { - const client = this.getElasticClient(); - - const primaryDocs = primaryKeys.map((primaryKey) => ({ - _id: primaryKey._id as string, - })); - const response = (await client.mget({ - index: tableName, - ids: primaryDocs.map((doc) => doc._id), - })) as MgetResponse>; - - let availableFields: string[] = []; - if (settings) { - const tableStructure = await this.getTableStructure(tableName); - availableFields = this.findAvailableFields(settings, tableStructure); - } - - return response.docs - .map((doc) => { - if ('error' in doc) { - return null; - } - const responseObject = { - ...(doc._source as Record), - _id: doc._id, - }; - if (availableFields.length > 0) { - Object.keys(responseObject).forEach((key) => { - if (!availableFields.includes(key)) { - // eslint-disable-next-line security/detect-object-injection - delete responseObject[key]; - } - }); - } - return responseObject; - }) - .filter((doc) => doc !== null); - } - - public async getRowsFromTable( - tableName: string, - settings: TableSettingsDS, - page: number, - perPage: number, - searchedFieldValue: string, - filteringFields: Array, - autocompleteFields: AutocompleteFieldsDS, - tableStructure: TableStructureDS[] | null, - ): Promise { - const client = this.getElasticClient(); - - page = page > 0 ? page : DAO_CONSTANTS.DEFAULT_PAGINATION.page; - - perPage = - perPage > 0 - ? perPage - : settings.list_per_page > 0 - ? settings.list_per_page - : DAO_CONSTANTS.DEFAULT_PAGINATION.perPage; - - const from = (page - 1) * perPage; - const searchQuery: any = { - index: tableName, - from, - size: perPage, - query: { - bool: { - must: [], - must_not: [], - }, - }, - }; - - if (autocompleteFields?.value && autocompleteFields.fields?.length > 0) { - const { fields, value } = autocompleteFields; - searchQuery.query.bool.must.push({ - multi_match: { - query: value as string, - fields: fields, - type: 'phrase_prefix', - }, - }); - searchQuery.size = DAO_CONSTANTS.AUTOCOMPLETE_ROW_LIMIT; - } - - if (!tableStructure) { - tableStructure = await this.getTableStructure(tableName); - } - - let { search_fields } = settings; - if ((!search_fields || search_fields.length === 0) && searchedFieldValue) { - search_fields = tableStructure.map((field) => field.column_name); - } - - if (searchedFieldValue && search_fields?.length > 0) { - const textFields = tableStructure - .filter((field) => field.data_type === 'string') - .map((field) => field.column_name); - - const validSearchFields = search_fields.filter((field) => textFields.includes(field)); - - if (validSearchFields.length) { - searchQuery.query.bool.must.push({ - multi_match: { - query: searchedFieldValue, - fields: validSearchFields, - type: 'phrase_prefix', - }, - }); - } - } - - if (filteringFields?.length > 0) { - for (const filter of filteringFields) { - const { field, criteria, value } = filter; - - switch (criteria) { - case FilterCriteriaEnum.eq: - searchQuery.query.bool.must.push({ term: { [field]: value } }); - break; - case FilterCriteriaEnum.contains: - searchQuery.query.bool.must.push({ - wildcard: { [field]: `*${value}*` }, - }); - break; - case FilterCriteriaEnum.gt: - searchQuery.query.bool.must.push({ range: { [field]: { gt: value } } }); - break; - case FilterCriteriaEnum.lt: - searchQuery.query.bool.must.push({ range: { [field]: { lt: value } } }); - break; - case FilterCriteriaEnum.gte: - searchQuery.query.bool.must.push({ range: { [field]: { gte: value } } }); - break; - case FilterCriteriaEnum.lte: - searchQuery.query.bool.must.push({ range: { [field]: { lte: value } } }); - break; - case FilterCriteriaEnum.icontains: - searchQuery.query.bool.must_not.push({ - wildcard: { [field]: `*${value}*` }, - }); - break; - case FilterCriteriaEnum.startswith: - searchQuery.query.bool.must.push({ - prefix: { [field]: value as string }, - }); - break; - case FilterCriteriaEnum.endswith: - searchQuery.query.bool.must.push({ - wildcard: { [field]: `*${value}` }, - }); - break; - case FilterCriteriaEnum.empty: - searchQuery.query.bool.must_not.push({ - exists: { field }, - }); - break; - } - } - } - - if ( - !autocompleteFields?.value && - (!searchedFieldValue || search_fields?.length === 0) && - (!filteringFields || filteringFields.length === 0) - ) { - searchQuery.query = { match_all: {} }; - } - - if (settings.ordering_field && settings.ordering) { - searchQuery.sort = [{ [settings.ordering_field]: settings.ordering.toLowerCase() }]; - } - - const response = await client.search(searchQuery); - - const total = response.hits.total as { value: number }; - - const rows = response.hits.hits.map((hit) => ({ - ...(hit._source as Record), - _id: hit._id, - })); - - let availableFields: string[] = []; - if (settings) { - const tableStructure = await this.getTableStructure(tableName); - availableFields = this.findAvailableFields(settings, tableStructure); - } - - if (availableFields.length > 0) { - rows.forEach((row) => { - Object.keys(row).forEach((key) => { - if (!availableFields.includes(key) && key !== '_id') { - // eslint-disable-next-line security/detect-object-injection - delete row[key]; - } - }); - }); - } - - return { - data: rows, - pagination: { - total: total.value, - lastPage: Math.ceil(total.value / perPage), - perPage, - currentPage: page, - }, - large_dataset: total.value > DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT, - }; - } - - public async getTableForeignKeys(_tableName: string): Promise> { - return []; - } - - public async getTablePrimaryColumns(_tableName: string): Promise> { - return [ - { - column_name: '_id', - data_type: 'string', - }, - ]; - } - - public async getTablesFromDB(): Promise> { - const client = this.getElasticClient(); - const response = await client.cat.indices({ - format: 'json', - }); - return response.map((index) => ({ - tableName: index.index, - isView: false, - })); - } - - public async getTableStructure(tableName: string): Promise> { - const client = this.getElasticClient(); - - const mappingResponse = await client.indices.getMapping({ - index: tableName, - }); - - const indexName = Object.keys(mappingResponse)[0]; - // eslint-disable-next-line security/detect-object-injection - const properties = mappingResponse[indexName]?.mappings?.properties || {}; - - const structure: TableStructureDS[] = [ - { - column_name: '_id', - data_type: 'string', - allow_null: false, - character_maximum_length: null, - column_default: null, - data_type_params: null, - udt_name: null, - extra: null, - }, - ]; - - for (const [fieldName, fieldMapping] of Object.entries(properties)) { - const field = fieldMapping as any; - - structure.push({ - column_name: fieldName, - data_type: this.mapElasticsearchType(field.type || 'object'), - allow_null: true, - character_maximum_length: null, - column_default: null, - data_type_params: null, - udt_name: null, - extra: null, - }); - } - - const searchResponse = await client.search({ - index: tableName, - size: 100, - query: { match_all: {} }, - }); - - const documents = searchResponse.hits.hits.map((hit) => hit._source); - - const fieldSet = new Set(); - documents.forEach((doc) => { - if (doc) { - Object.keys(doc).forEach((key) => fieldSet.add(key)); - } - }); - - fieldSet.forEach((fieldName) => { - if (!structure.some((field) => field.column_name === fieldName)) { - // eslint-disable-next-line security/detect-object-injection - const sampleValue = documents.find((doc) => doc && doc[fieldName] !== undefined)?.[fieldName]; - structure.push({ - column_name: fieldName, - data_type: this.inferFieldType(sampleValue), - allow_null: sampleValue === null || sampleValue === undefined, - character_maximum_length: null, - column_default: null, - data_type_params: null, - udt_name: null, - extra: null, - }); - } - }); - - return structure; - } - - public async testConnect(): Promise { - const client = this.getElasticClient(); - - try { - const _response = await client.cluster.health({ - timeout: '5s', - }); - - return { - result: true, - message: `Successfully connected`, - }; - } catch (error) { - return { - result: false, - message: error.message || 'Connection failed', - }; - } finally { - await client.close(); - } - } - - public async updateRowInTable( - tableName: string, - row: Record, - primaryKey: Record, - ): Promise> { - const client = this.getElasticClient(); - const primaryKeyValue = primaryKey._id as string; - delete row._id; - try { - await client.update({ - index: tableName, - id: primaryKeyValue, - doc: row, - }); - await client.indices.refresh({ index: tableName }); - return { _id: primaryKeyValue, ...row }; - } catch (error) { - throw new Error(`Failed to update document: ${error.message}`); - } - } - - public async bulkUpdateRowsInTable( - tableName: string, - newValues: Record, - primaryKeys: Array>, - ): Promise>> { - if (primaryKeys.length === 0) { - return []; - } - - const client = this.getElasticClient(); - - const body = primaryKeys.flatMap((primaryKey) => { - const documentId = primaryKey._id as string; - const updateQuery = { ...newValues }; - delete updateQuery._id; - return [{ update: { _index: tableName, _id: documentId } }, { doc: updateQuery }]; - }); - - const response = await client.bulk({ refresh: true, body }); - const erroredDocuments = response.items.filter((item) => item.update.error); - if (erroredDocuments.length > 0) { - throw new Error(`Failed to update some documents: ${erroredDocuments.map((doc) => doc.update.error).join(', ')}`); - } - await client.indices.refresh({ index: tableName }); - return primaryKeys.map((primaryKey) => ({ _id: primaryKey._id })); - } - - public async bulkDeleteRowsInTable(tableName: string, primaryKeys: Array>): Promise { - if (primaryKeys.length === 0) { - return 0; - } - - const client = this.getElasticClient(); - - const body = primaryKeys.map((primaryKey) => { - const documentId = primaryKey._id as string; - return { delete: { _index: tableName, _id: documentId } }; - }); - - const response = await client.bulk({ refresh: true, body }); - const successfulDeletes = response.items.filter((item) => !item.delete.error).length; - - const erroredDeletes = response.items.filter((item) => item.delete.error); - if (erroredDeletes.length > 0) { - throw new Error(`Failed to delete some documents: ${erroredDeletes.map((doc) => doc.delete.error).join(', ')}`); - } - await client.indices.refresh({ index: tableName }); - return successfulDeletes; - } - - public async validateSettings(settings: ValidateTableSettingsDS, tableName: string): Promise> { - const [tableStructure, primaryColumns] = await Promise.all([ - this.getTableStructure(tableName), - this.getTablePrimaryColumns(tableName), - ]); - return tableSettingsFieldValidator(tableStructure, primaryColumns, settings); - } - - public async getReferencedTableNamesAndColumns(_tableName: string): Promise> { - return []; - } - - public async isView(_tableName: string): Promise { - return false; - } - - public async getTableRowsStream( - tableName: string, - settings: TableSettingsDS, - page: number, - perPage: number, - searchedFieldValue: string, - filteringFields: FilteringFieldsDS[], - ): Promise> { - const result = await this.getRowsFromTable( - tableName, - settings, - page, - perPage, - searchedFieldValue, - filteringFields, - null, - null, - ); - return result.data as any; - } - - public async importCSVInTable(file: Express.Multer.File, tableName: string): Promise { - const client = this.getElasticClient(); - const stream = new Readable(); - stream.push(file.buffer); - stream.push(null); - - const parser = stream.pipe(csv.parse({ columns: true })); - - const actions = []; - for await (const record of parser) { - actions.push({ index: { _index: tableName } }); - actions.push(record); - } - - if (actions.length > 0) { - try { - const response = await client.bulk({ refresh: true, body: actions }); - const erroredDocuments = response.items.filter((item) => item.index?.error); - if (erroredDocuments.length > 0) { - throw new Error( - `Failed to index some documents: ${erroredDocuments.map((doc) => doc.index.error).join(', ')}`, - ); - } - } catch (error) { - throw new Error(`CSV import failed: ${error.message}`); - } - } - } - - public async executeRawQuery(query: string, tableName: string): Promise>> { - const client = this.getElasticClient(); - - const parsedQuery = JSON.parse(query); - const response = await client.search({ - index: tableName, - body: parsedQuery, - }); - - return response.hits.hits.map((hit) => ({ - ...(hit._source as Record), - _id: hit._id, - })); - } - - private getElasticClient(): Client { - const { host, port, username, password, ssl, cert } = this.connection; - const protocol = ssl ? 'https' : 'http'; - const node = `${protocol}://${host}:${port}`; - const options: any = { - node, - auth: { - username, - password, - }, - }; - if (ssl) { - options.tls = { - rejectUnauthorized: !cert, - }; - - if (cert) { - options.tls.ca = cert; - } - } - return new Client(options); - } - - private mapElasticsearchType(esType: string): string { - const typeMapping: { [key: string]: string } = { - text: 'string', - keyword: 'string', - long: 'number', - integer: 'number', - short: 'number', - byte: 'number', - double: 'number', - float: 'number', - half_float: 'number', - scaled_float: 'number', - boolean: 'boolean', - date: 'date', - object: 'object', - nested: 'array', - array: 'array', - binary: 'binary', - range: 'range', - ip: 'string', - version: 'string', - murmur3: 'string', - geo_point: 'geo_point', - geo_shape: 'geo_shape', - completion: 'string', - token_count: 'number', - dense_vector: 'array', - rank_feature: 'number', - rank_features: 'object', - }; - - // eslint-disable-next-line security/detect-object-injection - return typeMapping[esType] || 'string'; - } - - private inferFieldType(value: any): string { - if (typeof value === 'string') { - return 'string'; - } else if (typeof value === 'number') { - return 'number'; - } else if (value instanceof Date || !Number.isNaN(Date.parse(value))) { - return 'date'; - } else if (typeof value === 'boolean') { - return 'boolean'; - } else if (Array.isArray(value)) { - return 'array'; - } else if (typeof value === 'object') { - return 'object'; - } - return 'unknown'; - } + public async addRowInTable( + tableName: string, + row: Record, + ): Promise | number> { + const client = this.getElasticClient(); + const response = await client.index({ + index: tableName, + document: row, + }); + await client.indices.refresh({ index: tableName }); + return { _id: response._id, ...row }; + } + + public async deleteRowInTable( + tableName: string, + primaryKey: Record, + ): Promise> { + const client = this.getElasticClient(); + const response = await client.delete({ + index: tableName, + id: primaryKey._id as string, + }); + if (response.result !== 'deleted') { + throw new Error('Document was not deleted successfully'); + } + await client.indices.refresh({ index: tableName }); + return { _id: primaryKey._id }; + } + + public async getIdentityColumns( + tableName: string, + referencedFieldName: string, + identityColumnName: string, + fieldValues: Array, + ): Promise>> { + const client = this.getElasticClient(); + const query = { + index: tableName, + body: { + query: { + terms: { + [referencedFieldName]: fieldValues, + }, + }, + _source: { + includes: identityColumnName ? [referencedFieldName, identityColumnName] : [referencedFieldName], + }, + }, + } as const; + + const response = await client.search(query as any); + + return response.hits.hits.map((hit) => { + const source = hit._source as Record; + return { + ...source, + _id: hit._id, + }; + }); + } + + public async getRowByPrimaryKey( + tableName: string, + primaryKey: Record, + settings: TableSettingsDS, + ): Promise> { + const primaryKeyValue = primaryKey._id; + const client = this.getElasticClient(); + let responseObject = {} as Record; + try { + const response = await client.get({ + index: tableName, + id: primaryKeyValue as string, + }); + responseObject = { + ...(response._source as Record), + _id: response._id, + }; + } catch (error) { + if (error.meta?.body?.found === false) { + return null; + } + throw error; + } + + let availableFields: string[] = []; + if (settings) { + const tableStructure = await this.getTableStructure(tableName); + availableFields = this.findAvailableFields(settings, tableStructure); + } + + if (availableFields.length > 0) { + Object.keys(responseObject).forEach((key) => { + if (!availableFields.includes(key)) { + // eslint-disable-next-line security/detect-object-injection + delete responseObject[key]; + } + }); + } + + return responseObject; + } + + public async bulkGetRowsFromTableByPrimaryKeys( + tableName: string, + primaryKeys: Array>, + settings: TableSettingsDS, + ): Promise>> { + const client = this.getElasticClient(); + + const primaryDocs = primaryKeys.map((primaryKey) => ({ + _id: primaryKey._id as string, + })); + const response = (await client.mget({ + index: tableName, + ids: primaryDocs.map((doc) => doc._id), + })) as MgetResponse>; + + let availableFields: string[] = []; + if (settings) { + const tableStructure = await this.getTableStructure(tableName); + availableFields = this.findAvailableFields(settings, tableStructure); + } + + return response.docs + .map((doc) => { + if ('error' in doc) { + return null; + } + const responseObject = { + ...(doc._source as Record), + _id: doc._id, + }; + if (availableFields.length > 0) { + Object.keys(responseObject).forEach((key) => { + if (!availableFields.includes(key)) { + // eslint-disable-next-line security/detect-object-injection + delete responseObject[key]; + } + }); + } + return responseObject; + }) + .filter((doc) => doc !== null); + } + + public async getRowsFromTable( + tableName: string, + settings: TableSettingsDS, + page: number, + perPage: number, + searchedFieldValue: string, + filteringFields: Array, + autocompleteFields: AutocompleteFieldsDS, + tableStructure: TableStructureDS[] | null, + ): Promise { + const client = this.getElasticClient(); + + page = page > 0 ? page : DAO_CONSTANTS.DEFAULT_PAGINATION.page; + + perPage = + perPage > 0 + ? perPage + : settings.list_per_page > 0 + ? settings.list_per_page + : DAO_CONSTANTS.DEFAULT_PAGINATION.perPage; + + const from = (page - 1) * perPage; + const searchQuery: any = { + index: tableName, + from, + size: perPage, + query: { + bool: { + must: [], + must_not: [], + }, + }, + }; + + if (autocompleteFields?.value && autocompleteFields.fields?.length > 0) { + const { fields, value } = autocompleteFields; + searchQuery.query.bool.must.push({ + multi_match: { + query: value as string, + fields: fields, + type: 'phrase_prefix', + }, + }); + searchQuery.size = DAO_CONSTANTS.AUTOCOMPLETE_ROW_LIMIT; + } + + if (!tableStructure) { + tableStructure = await this.getTableStructure(tableName); + } + + let { search_fields } = settings; + if ((!search_fields || search_fields.length === 0) && searchedFieldValue) { + search_fields = tableStructure.map((field) => field.column_name); + } + + if (searchedFieldValue && search_fields?.length > 0) { + const textFields = tableStructure + .filter((field) => field.data_type === 'string') + .map((field) => field.column_name); + + const validSearchFields = search_fields.filter((field) => textFields.includes(field)); + + if (validSearchFields.length) { + searchQuery.query.bool.must.push({ + multi_match: { + query: searchedFieldValue, + fields: validSearchFields, + type: 'phrase_prefix', + }, + }); + } + } + + if (filteringFields?.length > 0) { + for (const filter of filteringFields) { + const { field, criteria, value } = filter; + + switch (criteria) { + case FilterCriteriaEnum.eq: + searchQuery.query.bool.must.push({ term: { [field]: value } }); + break; + case FilterCriteriaEnum.contains: + searchQuery.query.bool.must.push({ + wildcard: { [field]: `*${value}*` }, + }); + break; + case FilterCriteriaEnum.gt: + searchQuery.query.bool.must.push({ range: { [field]: { gt: value } } }); + break; + case FilterCriteriaEnum.lt: + searchQuery.query.bool.must.push({ range: { [field]: { lt: value } } }); + break; + case FilterCriteriaEnum.gte: + searchQuery.query.bool.must.push({ range: { [field]: { gte: value } } }); + break; + case FilterCriteriaEnum.lte: + searchQuery.query.bool.must.push({ range: { [field]: { lte: value } } }); + break; + case FilterCriteriaEnum.icontains: + searchQuery.query.bool.must_not.push({ + wildcard: { [field]: `*${value}*` }, + }); + break; + case FilterCriteriaEnum.startswith: + searchQuery.query.bool.must.push({ + prefix: { [field]: value as string }, + }); + break; + case FilterCriteriaEnum.endswith: + searchQuery.query.bool.must.push({ + wildcard: { [field]: `*${value}` }, + }); + break; + case FilterCriteriaEnum.empty: + searchQuery.query.bool.must_not.push({ + exists: { field }, + }); + break; + } + } + } + + if ( + !autocompleteFields?.value && + (!searchedFieldValue || search_fields?.length === 0) && + (!filteringFields || filteringFields.length === 0) + ) { + searchQuery.query = { match_all: {} }; + } + + if (settings.ordering_field && settings.ordering) { + searchQuery.sort = [{ [settings.ordering_field]: settings.ordering.toLowerCase() }]; + } + + const response = await client.search(searchQuery); + + const total = response.hits.total as { value: number }; + + const rows = response.hits.hits.map((hit) => ({ + ...(hit._source as Record), + _id: hit._id, + })); + + let availableFields: string[] = []; + if (settings) { + const tableStructure = await this.getTableStructure(tableName); + availableFields = this.findAvailableFields(settings, tableStructure); + } + + if (availableFields.length > 0) { + rows.forEach((row) => { + Object.keys(row).forEach((key) => { + if (!availableFields.includes(key) && key !== '_id') { + // eslint-disable-next-line security/detect-object-injection + delete row[key]; + } + }); + }); + } + + return { + data: rows, + pagination: { + total: total.value, + lastPage: Math.ceil(total.value / perPage), + perPage, + currentPage: page, + }, + large_dataset: total.value > DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT, + }; + } + + public async getTableForeignKeys(_tableName: string): Promise> { + return []; + } + + public async getTablePrimaryColumns(_tableName: string): Promise> { + return [ + { + column_name: '_id', + data_type: 'string', + }, + ]; + } + + public async getTablesFromDB(): Promise> { + const client = this.getElasticClient(); + const response = await client.cat.indices({ + format: 'json', + }); + return response.map((index) => ({ + tableName: index.index, + isView: false, + })); + } + + public async getTableStructure(tableName: string): Promise> { + const client = this.getElasticClient(); + + const mappingResponse = await client.indices.getMapping({ + index: tableName, + }); + + const indexName = Object.keys(mappingResponse)[0]; + // eslint-disable-next-line security/detect-object-injection + const properties = mappingResponse[indexName]?.mappings?.properties || {}; + + const structure: TableStructureDS[] = [ + { + column_name: '_id', + data_type: 'string', + allow_null: false, + character_maximum_length: null, + column_default: null, + data_type_params: null, + udt_name: null, + extra: null, + }, + ]; + + for (const [fieldName, fieldMapping] of Object.entries(properties)) { + const field = fieldMapping as any; + + structure.push({ + column_name: fieldName, + data_type: this.mapElasticsearchType(field.type || 'object'), + allow_null: true, + character_maximum_length: null, + column_default: null, + data_type_params: null, + udt_name: null, + extra: null, + }); + } + + const searchResponse = await client.search({ + index: tableName, + size: 100, + query: { match_all: {} }, + }); + + const documents = searchResponse.hits.hits.map((hit) => hit._source); + + const fieldSet = new Set(); + documents.forEach((doc) => { + if (doc) { + Object.keys(doc).forEach((key) => fieldSet.add(key)); + } + }); + + fieldSet.forEach((fieldName) => { + if (!structure.some((field) => field.column_name === fieldName)) { + // eslint-disable-next-line security/detect-object-injection + const sampleValue = documents.find((doc) => doc && doc[fieldName] !== undefined)?.[fieldName]; + structure.push({ + column_name: fieldName, + data_type: this.inferFieldType(sampleValue), + allow_null: sampleValue === null || sampleValue === undefined, + character_maximum_length: null, + column_default: null, + data_type_params: null, + udt_name: null, + extra: null, + }); + } + }); + + return structure; + } + + public async testConnect(): Promise { + const client = this.getElasticClient(); + + try { + const _response = await client.cluster.health({ + timeout: '5s', + }); + + return { + result: true, + message: `Successfully connected`, + }; + } catch (error) { + return { + result: false, + message: error.message || 'Connection failed', + }; + } finally { + await client.close(); + } + } + + public async updateRowInTable( + tableName: string, + row: Record, + primaryKey: Record, + ): Promise> { + const client = this.getElasticClient(); + const primaryKeyValue = primaryKey._id as string; + delete row._id; + try { + await client.update({ + index: tableName, + id: primaryKeyValue, + doc: row, + }); + await client.indices.refresh({ index: tableName }); + return { _id: primaryKeyValue, ...row }; + } catch (error) { + throw new Error(`Failed to update document: ${error.message}`); + } + } + + public async bulkUpdateRowsInTable( + tableName: string, + newValues: Record, + primaryKeys: Array>, + ): Promise>> { + if (primaryKeys.length === 0) { + return []; + } + + const client = this.getElasticClient(); + + const body = primaryKeys.flatMap((primaryKey) => { + const documentId = primaryKey._id as string; + const updateQuery = { ...newValues }; + delete updateQuery._id; + return [{ update: { _index: tableName, _id: documentId } }, { doc: updateQuery }]; + }); + + const response = await client.bulk({ refresh: true, body }); + const erroredDocuments = response.items.filter((item) => item.update.error); + if (erroredDocuments.length > 0) { + throw new Error(`Failed to update some documents: ${erroredDocuments.map((doc) => doc.update.error).join(', ')}`); + } + await client.indices.refresh({ index: tableName }); + return primaryKeys.map((primaryKey) => ({ _id: primaryKey._id })); + } + + public async bulkDeleteRowsInTable(tableName: string, primaryKeys: Array>): Promise { + if (primaryKeys.length === 0) { + return 0; + } + + const client = this.getElasticClient(); + + const body = primaryKeys.map((primaryKey) => { + const documentId = primaryKey._id as string; + return { delete: { _index: tableName, _id: documentId } }; + }); + + const response = await client.bulk({ refresh: true, body }); + const successfulDeletes = response.items.filter((item) => !item.delete.error).length; + + const erroredDeletes = response.items.filter((item) => item.delete.error); + if (erroredDeletes.length > 0) { + throw new Error(`Failed to delete some documents: ${erroredDeletes.map((doc) => doc.delete.error).join(', ')}`); + } + await client.indices.refresh({ index: tableName }); + return successfulDeletes; + } + + public async validateSettings(settings: ValidateTableSettingsDS, tableName: string): Promise> { + const [tableStructure, primaryColumns] = await Promise.all([ + this.getTableStructure(tableName), + this.getTablePrimaryColumns(tableName), + ]); + return tableSettingsFieldValidator(tableStructure, primaryColumns, settings); + } + + public async getReferencedTableNamesAndColumns(_tableName: string): Promise> { + return []; + } + + public async isView(_tableName: string): Promise { + return false; + } + + public async getTableRowsStream( + tableName: string, + settings: TableSettingsDS, + page: number, + perPage: number, + searchedFieldValue: string, + filteringFields: FilteringFieldsDS[], + ): Promise> { + const result = await this.getRowsFromTable( + tableName, + settings, + page, + perPage, + searchedFieldValue, + filteringFields, + null, + null, + ); + return result.data as any; + } + + public async importCSVInTable(file: Express.Multer.File, tableName: string): Promise { + const client = this.getElasticClient(); + const stream = new Readable(); + stream.push(file.buffer); + stream.push(null); + + const parser = stream.pipe(csv.parse({ columns: true })); + + const actions = []; + for await (const record of parser) { + actions.push({ index: { _index: tableName } }); + actions.push(record); + } + + if (actions.length > 0) { + try { + const response = await client.bulk({ refresh: true, body: actions }); + const erroredDocuments = response.items.filter((item) => item.index?.error); + if (erroredDocuments.length > 0) { + throw new Error( + `Failed to index some documents: ${erroredDocuments.map((doc) => doc.index.error).join(', ')}`, + ); + } + } catch (error) { + throw new Error(`CSV import failed: ${error.message}`); + } + } + } + + public async executeRawQuery(query: string, tableName: string): Promise>> { + const client = this.getElasticClient(); + + const parsedQuery = JSON.parse(query); + const response = await client.search({ + index: tableName, + body: parsedQuery, + }); + + return response.hits.hits.map((hit) => ({ + ...(hit._source as Record), + _id: hit._id, + })); + } + + private getElasticClient(): Client { + const { host, port, username, password, ssl, cert } = this.connection; + const protocol = ssl ? 'https' : 'http'; + const node = `${protocol}://${host}:${port}`; + const options: any = { + node, + auth: { + username, + password, + }, + }; + if (ssl) { + options.tls = { + rejectUnauthorized: !cert, + }; + + if (cert) { + options.tls.ca = cert; + } + } + return new Client(options); + } + + private mapElasticsearchType(esType: string): string { + const typeMapping: { [key: string]: string } = { + text: 'string', + keyword: 'string', + long: 'number', + integer: 'number', + short: 'number', + byte: 'number', + double: 'number', + float: 'number', + half_float: 'number', + scaled_float: 'number', + boolean: 'boolean', + date: 'date', + object: 'object', + nested: 'array', + array: 'array', + binary: 'binary', + range: 'range', + ip: 'string', + version: 'string', + murmur3: 'string', + geo_point: 'geo_point', + geo_shape: 'geo_shape', + completion: 'string', + token_count: 'number', + dense_vector: 'array', + rank_feature: 'number', + rank_features: 'object', + }; + + // eslint-disable-next-line security/detect-object-injection + return typeMapping[esType] || 'string'; + } + + private inferFieldType(value: any): string { + if (typeof value === 'string') { + return 'string'; + } else if (typeof value === 'number') { + return 'number'; + } else if (value instanceof Date || !Number.isNaN(Date.parse(value))) { + return 'date'; + } else if (typeof value === 'boolean') { + return 'boolean'; + } else if (Array.isArray(value)) { + return 'array'; + } else if (typeof value === 'object') { + return 'object'; + } + return 'unknown'; + } } diff --git a/shared-code/src/data-access-layer/data-access-objects/data-access-object-mssql.ts b/shared-code/src/data-access-layer/data-access-objects/data-access-object-mssql.ts index 3384ca64a..2bca06f9d 100644 --- a/shared-code/src/data-access-layer/data-access-objects/data-access-object-mssql.ts +++ b/shared-code/src/data-access-layer/data-access-objects/data-access-object-mssql.ts @@ -27,235 +27,234 @@ import { IDataAccessObject } from '../../shared/interfaces/data-access-object.in import { BasicDataAccessObject } from './basic-data-access-object.js'; export class DataAccessObjectMssql extends BasicDataAccessObject implements IDataAccessObject { - - public async addRowInTable( - tableName: string, - row: Record, - ): Promise> { - const knex = await this.configureKnex(); - const primaryColumns = await this.getTablePrimaryColumns(tableName); - const primaryKeys = primaryColumns.map(({ column_name }) => column_name); - const schemaName = await this.getSchemaName(tableName); - - const keysToReturn = primaryColumns?.length > 0 ? primaryKeys : Object.keys(row); - const result = await knex(`${schemaName}.[${tableName}]`).returning(keysToReturn).insert(row); - - return result[0]; - } - - public async deleteRowInTable( - tableName: string, - primaryKey: Record, - ): Promise> { - const knex = await this.configureKnex(); - const schemaName = await this.getSchemaName(tableName); - tableName = `${schemaName}.[${tableName}]`; - return await knex(tableName).returning(Object.keys(primaryKey)).where(primaryKey).del(); - } - - public async getIdentityColumns( - tableName: string, - referencedFieldName: string, - identityColumnName: string, - fieldValues: (string | number)[], - ): Promise>> { - const knex = await this.configureKnex(); - const schemaName = await this.getSchemaName(tableName); - tableName = `${schemaName}.[${tableName}]`; - const columnsToSelect = identityColumnName ? [referencedFieldName, identityColumnName] : [referencedFieldName]; - return knex(tableName).select(columnsToSelect).whereIn(referencedFieldName, fieldValues); - } - - public async getRowByPrimaryKey( - tableName: string, - primaryKey: Record, - tableSettings: TableSettingsDS, - ): Promise> { - const knex = await this.configureKnex(); - const schemaName = await this.getSchemaName(tableName); - tableName = `${schemaName}.[${tableName}]`; - - let fieldsToSelect: string | Array = '*'; - if (tableSettings) { - const tableStructure = await this.getTableStructure(tableName); - fieldsToSelect = this.findAvailableFields(tableSettings, tableStructure); - } - - return (await knex(tableName).select(fieldsToSelect).where(primaryKey))[0] as unknown as Record; - } - - public async bulkGetRowsFromTableByPrimaryKeys( - tableName: string, - primaryKeys: Array>, - settings: TableSettingsDS, - ): Promise>> { - const knex = await this.configureKnex(); - const schemaName = await this.getSchemaName(tableName); - tableName = `${schemaName}.[${tableName}]`; - let availableFields: string[] = []; - - if (settings) { - const tableStructure = await this.getTableStructure(tableName); - availableFields = this.findAvailableFields(settings, tableStructure); - } - - const query = knex(tableName).select(availableFields.length ? availableFields : '*'); - - primaryKeys.forEach((primaryKey) => { - query.orWhere((builder) => { - Object.entries(primaryKey).forEach(([column, value]) => { - builder.andWhere(column, value); - }); - }); - }); - - const results = await query; - return results as Array>; - } - - public async getRowsFromTable( - receivedTableName: string, - tableSettings: TableSettingsDS, - page: number, - perPage: number, - searchedFieldValue: string, - filteringFields: FilteringFieldsDS[], - autocompleteFields: AutocompleteFieldsDS, - tableStructure: TableStructureDS[] | null, - ): Promise { - page = page > 0 ? page : DAO_CONSTANTS.DEFAULT_PAGINATION.page; - perPage = - perPage > 0 - ? perPage - : tableSettings.list_per_page > 0 - ? tableSettings.list_per_page - : DAO_CONSTANTS.DEFAULT_PAGINATION.perPage; - - const knex = await this.configureKnex(); - - if (!tableStructure) { - tableStructure = await this.getTableStructure(receivedTableName); - } - const tableSchema = await this.getSchemaName(receivedTableName); - - const availableFields = this.findAvailableFields(tableSettings, tableStructure); - const tableNameWithoutSchema = receivedTableName; - const tableNameWithSchema = tableSchema ? `${tableSchema}.[${receivedTableName}]` : receivedTableName; - - if (autocompleteFields?.value && autocompleteFields.fields.length > 0) { - const rows = await knex(tableNameWithSchema) - .select(autocompleteFields.fields) - .modify((builder) => { - if (autocompleteFields.value !== '*') { - autocompleteFields.fields.forEach((field) => { - builder.orWhere(field, 'like', `${autocompleteFields.value}%`); - }); - } - }) - .limit(DAO_CONSTANTS.AUTOCOMPLETE_ROW_LIMIT); - - const rowsCount = await this.getRowsCount(tableNameWithoutSchema, null); - - return { - data: rows, - pagination: {} as any, - large_dataset: rowsCount >= DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT, - }; - } - - tableSettings.ordering_field = tableSettings?.ordering_field || availableFields[0]; - tableSettings.ordering = tableSettings?.ordering || QueryOrderingEnum.ASC; - - const fastRowsCount = await this.getFastRowsCount(receivedTableName); - const rowsCountQuery = knex(tableNameWithSchema) - .modify((builder) => { - let search_fields = tableSettings?.search_fields || []; - - if (search_fields.length === 0 && searchedFieldValue) { - search_fields = availableFields; - } - - if (searchedFieldValue) { - search_fields.forEach((field) => { - if (Buffer.isBuffer(searchedFieldValue)) { - builder.orWhere(field, '=', searchedFieldValue); - } else { - if (fastRowsCount <= 1000) { - builder.orWhereRaw(`LOWER(CAST(?? AS CHAR(255))) LIKE ?`, [ - field, - `%${searchedFieldValue.toLowerCase()}%`, - ]); - } - builder.orWhereRaw(`LOWER(CAST(?? AS CHAR(255))) LIKE ?`, [ - field, - `${searchedFieldValue.toLowerCase()}%`, - ]); - } - }); - } - }) - .modify((builder) => { - if (filteringFields?.length > 0) { - for (const { field, criteria, value } of filteringFields) { - const operators = { - [FilterCriteriaEnum.eq]: '=', - [FilterCriteriaEnum.startswith]: 'like', - [FilterCriteriaEnum.endswith]: 'like', - [FilterCriteriaEnum.gt]: '>', - [FilterCriteriaEnum.lt]: '<', - [FilterCriteriaEnum.lte]: '<=', - [FilterCriteriaEnum.gte]: '>=', - [FilterCriteriaEnum.contains]: 'like', - [FilterCriteriaEnum.icontains]: 'not like', - [FilterCriteriaEnum.empty]: 'is', - }; - - const values = { - [FilterCriteriaEnum.startswith]: `${value}%`, - [FilterCriteriaEnum.endswith]: `%${value}`, - [FilterCriteriaEnum.contains]: `%${value}%`, - [FilterCriteriaEnum.icontains]: `%${value}%`, - [FilterCriteriaEnum.empty]: null, - }; - builder.where(field, operators[criteria], values[criteria] || value); - } - } - }); - - const rowsDataQuery = rowsCountQuery.clone(); - - const rowsCount = await this.getRowsCount(tableNameWithoutSchema, rowsCountQuery); - - const { ordering_field, ordering } = tableSettings; - const rows = await rowsDataQuery - .select(availableFields) - .orderBy(ordering_field, ordering) - .limit(perPage) - .offset((page - 1) * perPage); - - const pagination = { - total: rowsCount, - lastPage: Math.ceil(rowsCount / perPage), - perPage, - currentPage: page, - }; - - return { - data: rows, - pagination, - large_dataset: rowsCount >= DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT, - }; - } - - public async getTableForeignKeys(tableName: string): Promise { - const cachedForeignKeys = LRUStorage.getTableForeignKeysCache(this.connection, tableName); - if (cachedForeignKeys) { - return cachedForeignKeys; - } - const knex = await this.configureKnex(); - const schema = await this.getSchemaNameWithoutBrackets(tableName); - const foreignKeys = await knex.raw( - `SELECT fk_kcu.constraint_name AS constraint_name + public async addRowInTable( + tableName: string, + row: Record, + ): Promise> { + const knex = await this.configureKnex(); + const primaryColumns = await this.getTablePrimaryColumns(tableName); + const primaryKeys = primaryColumns.map(({ column_name }) => column_name); + const schemaName = await this.getSchemaName(tableName); + + const keysToReturn = primaryColumns?.length > 0 ? primaryKeys : Object.keys(row); + const result = await knex(`${schemaName}.[${tableName}]`).returning(keysToReturn).insert(row); + + return result[0]; + } + + public async deleteRowInTable( + tableName: string, + primaryKey: Record, + ): Promise> { + const knex = await this.configureKnex(); + const schemaName = await this.getSchemaName(tableName); + tableName = `${schemaName}.[${tableName}]`; + return await knex(tableName).returning(Object.keys(primaryKey)).where(primaryKey).del(); + } + + public async getIdentityColumns( + tableName: string, + referencedFieldName: string, + identityColumnName: string, + fieldValues: (string | number)[], + ): Promise>> { + const knex = await this.configureKnex(); + const schemaName = await this.getSchemaName(tableName); + tableName = `${schemaName}.[${tableName}]`; + const columnsToSelect = identityColumnName ? [referencedFieldName, identityColumnName] : [referencedFieldName]; + return knex(tableName).select(columnsToSelect).whereIn(referencedFieldName, fieldValues); + } + + public async getRowByPrimaryKey( + tableName: string, + primaryKey: Record, + tableSettings: TableSettingsDS, + ): Promise> { + const knex = await this.configureKnex(); + const schemaName = await this.getSchemaName(tableName); + tableName = `${schemaName}.[${tableName}]`; + + let fieldsToSelect: string | Array = '*'; + if (tableSettings) { + const tableStructure = await this.getTableStructure(tableName); + fieldsToSelect = this.findAvailableFields(tableSettings, tableStructure); + } + + return (await knex(tableName).select(fieldsToSelect).where(primaryKey))[0] as unknown as Record; + } + + public async bulkGetRowsFromTableByPrimaryKeys( + tableName: string, + primaryKeys: Array>, + settings: TableSettingsDS, + ): Promise>> { + const knex = await this.configureKnex(); + const schemaName = await this.getSchemaName(tableName); + tableName = `${schemaName}.[${tableName}]`; + let availableFields: string[] = []; + + if (settings) { + const tableStructure = await this.getTableStructure(tableName); + availableFields = this.findAvailableFields(settings, tableStructure); + } + + const query = knex(tableName).select(availableFields.length ? availableFields : '*'); + + primaryKeys.forEach((primaryKey) => { + query.orWhere((builder) => { + Object.entries(primaryKey).forEach(([column, value]) => { + builder.andWhere(column, value); + }); + }); + }); + + const results = await query; + return results as Array>; + } + + public async getRowsFromTable( + receivedTableName: string, + tableSettings: TableSettingsDS, + page: number, + perPage: number, + searchedFieldValue: string, + filteringFields: FilteringFieldsDS[], + autocompleteFields: AutocompleteFieldsDS, + tableStructure: TableStructureDS[] | null, + ): Promise { + page = page > 0 ? page : DAO_CONSTANTS.DEFAULT_PAGINATION.page; + perPage = + perPage > 0 + ? perPage + : tableSettings.list_per_page > 0 + ? tableSettings.list_per_page + : DAO_CONSTANTS.DEFAULT_PAGINATION.perPage; + + const knex = await this.configureKnex(); + + if (!tableStructure) { + tableStructure = await this.getTableStructure(receivedTableName); + } + const tableSchema = await this.getSchemaName(receivedTableName); + + const availableFields = this.findAvailableFields(tableSettings, tableStructure); + const tableNameWithoutSchema = receivedTableName; + const tableNameWithSchema = tableSchema ? `${tableSchema}.[${receivedTableName}]` : receivedTableName; + + if (autocompleteFields?.value && autocompleteFields.fields.length > 0) { + const rows = await knex(tableNameWithSchema) + .select(autocompleteFields.fields) + .modify((builder) => { + if (autocompleteFields.value !== '*') { + autocompleteFields.fields.forEach((field) => { + builder.orWhere(field, 'like', `${autocompleteFields.value}%`); + }); + } + }) + .limit(DAO_CONSTANTS.AUTOCOMPLETE_ROW_LIMIT); + + const rowsCount = await this.getRowsCount(tableNameWithoutSchema, null); + + return { + data: rows, + pagination: {} as any, + large_dataset: rowsCount >= DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT, + }; + } + + tableSettings.ordering_field = tableSettings?.ordering_field || availableFields[0]; + tableSettings.ordering = tableSettings?.ordering || QueryOrderingEnum.ASC; + + const fastRowsCount = await this.getFastRowsCount(receivedTableName); + const rowsCountQuery = knex(tableNameWithSchema) + .modify((builder) => { + let search_fields = tableSettings?.search_fields || []; + + if (search_fields.length === 0 && searchedFieldValue) { + search_fields = availableFields; + } + + if (searchedFieldValue) { + search_fields.forEach((field) => { + if (Buffer.isBuffer(searchedFieldValue)) { + builder.orWhere(field, '=', searchedFieldValue); + } else { + if (fastRowsCount <= 1000) { + builder.orWhereRaw(`LOWER(CAST(?? AS CHAR(255))) LIKE ?`, [ + field, + `%${searchedFieldValue.toLowerCase()}%`, + ]); + } + builder.orWhereRaw(`LOWER(CAST(?? AS CHAR(255))) LIKE ?`, [ + field, + `${searchedFieldValue.toLowerCase()}%`, + ]); + } + }); + } + }) + .modify((builder) => { + if (filteringFields?.length > 0) { + for (const { field, criteria, value } of filteringFields) { + const operators = { + [FilterCriteriaEnum.eq]: '=', + [FilterCriteriaEnum.startswith]: 'like', + [FilterCriteriaEnum.endswith]: 'like', + [FilterCriteriaEnum.gt]: '>', + [FilterCriteriaEnum.lt]: '<', + [FilterCriteriaEnum.lte]: '<=', + [FilterCriteriaEnum.gte]: '>=', + [FilterCriteriaEnum.contains]: 'like', + [FilterCriteriaEnum.icontains]: 'not like', + [FilterCriteriaEnum.empty]: 'is', + }; + + const values = { + [FilterCriteriaEnum.startswith]: `${value}%`, + [FilterCriteriaEnum.endswith]: `%${value}`, + [FilterCriteriaEnum.contains]: `%${value}%`, + [FilterCriteriaEnum.icontains]: `%${value}%`, + [FilterCriteriaEnum.empty]: null, + }; + builder.where(field, operators[criteria], values[criteria] || value); + } + } + }); + + const rowsDataQuery = rowsCountQuery.clone(); + + const rowsCount = await this.getRowsCount(tableNameWithoutSchema, rowsCountQuery); + + const { ordering_field, ordering } = tableSettings; + const rows = await rowsDataQuery + .select(availableFields) + .orderBy(ordering_field, ordering) + .limit(perPage) + .offset((page - 1) * perPage); + + const pagination = { + total: rowsCount, + lastPage: Math.ceil(rowsCount / perPage), + perPage, + currentPage: page, + }; + + return { + data: rows, + pagination, + large_dataset: rowsCount >= DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT, + }; + } + + public async getTableForeignKeys(tableName: string): Promise { + const cachedForeignKeys = LRUStorage.getTableForeignKeysCache(this.connection, tableName); + if (cachedForeignKeys) { + return cachedForeignKeys; + } + const knex = await this.configureKnex(); + const schema = await this.getSchemaNameWithoutBrackets(tableName); + const foreignKeys = await knex.raw( + `SELECT fk_kcu.constraint_name AS constraint_name , fk_kcu.column_name AS column_name , pk_kcu.table_name AS referenced_table_name , pk_kcu.column_name AS referenced_column_name @@ -267,24 +266,24 @@ export class DataAccessObjectMssql extends BasicDataAccessObject implements IDat AND pk_kcu.ORDINAL_POSITION = fk_kcu.ORDINAL_POSITION WHERE fk_kcu.TABLE_NAME = ? AND fk_kcu.TABLE_SCHEMA = ?`, - [tableName, schema], - ); - - const foreignKeysInLowercase: ForeignKeyDS[] = foreignKeys.map(objectKeysToLowercase); - - LRUStorage.setTableForeignKeysCache(this.connection, tableName, foreignKeysInLowercase); - return foreignKeysInLowercase; - } - - public async getTablePrimaryColumns(tableName: string): Promise { - const cachedPrimaryColumns = LRUStorage.getTablePrimaryKeysCache(this.connection, tableName); - if (cachedPrimaryColumns) { - return cachedPrimaryColumns; - } - const knex = await this.configureKnex(); - const schema = await this.getSchemaNameWithoutBrackets(tableName); - const primaryColumns = await knex.raw( - `Select C.COLUMN_NAME + [tableName, schema], + ); + + const foreignKeysInLowercase: ForeignKeyDS[] = foreignKeys.map(objectKeysToLowercase); + + LRUStorage.setTableForeignKeysCache(this.connection, tableName, foreignKeysInLowercase); + return foreignKeysInLowercase; + } + + public async getTablePrimaryColumns(tableName: string): Promise { + const cachedPrimaryColumns = LRUStorage.getTablePrimaryKeysCache(this.connection, tableName); + if (cachedPrimaryColumns) { + return cachedPrimaryColumns; + } + const knex = await this.configureKnex(); + const schema = await this.getSchemaNameWithoutBrackets(tableName); + const primaryColumns = await knex.raw( + `Select C.COLUMN_NAME , C.DATA_TYPE From INFORMATION_SCHEMA.COLUMNS As C Outer Apply ( Select CCU.CONSTRAINT_NAME @@ -297,17 +296,17 @@ export class DataAccessObjectMssql extends BasicDataAccessObject implements IDat And CCU.COLUMN_NAME = C.COLUMN_NAME ) As Z Where C.TABLE_NAME = ? AND Z.CONSTRAINT_NAME is not null AND C.TABLE_SCHEMA = ?;`, - [tableName, schema], - ); + [tableName, schema], + ); - const primaryColumnsInLowercase: PrimaryKeyDS[] = primaryColumns.map(objectKeysToLowercase); - LRUStorage.setTablePrimaryKeysCache(this.connection, tableName, primaryColumnsInLowercase); - return primaryColumnsInLowercase; - } + const primaryColumnsInLowercase: PrimaryKeyDS[] = primaryColumns.map(objectKeysToLowercase); + LRUStorage.setTablePrimaryKeysCache(this.connection, tableName, primaryColumnsInLowercase); + return primaryColumnsInLowercase; + } - public async getTablesFromDB(): Promise { - const knex = await this.configureKnex(); - const query = ` + public async getTablesFromDB(): Promise { + const knex = await this.configureKnex(); + const query = ` SELECT TABLE_NAME, CASE WHEN TABLE_TYPE = 'BASE TABLE' THEN 0 @@ -324,150 +323,150 @@ SELECT TABLE_NAME, FROM ??.INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'VIEW' `; - const result = await knex.raw(query, [this.connection.database, this.connection.database]); - - return result.map(({ TABLE_NAME, isView }: { TABLE_NAME: string; isView: number }) => ({ - tableName: TABLE_NAME, - isView: isView === 1, - })); - } - - public async getTableStructure(tableName: string): Promise { - const cachedTableStructure = LRUStorage.getTableStructureCache(this.connection, tableName); - if (cachedTableStructure) { - return cachedTableStructure; - } - const { database } = this.connection; - const knex = await this.configureKnex(); - const schema = await this.getSchemaNameWithoutBrackets(tableName); - const structureColumns = await knex('information_schema.COLUMNS') - .select('COLUMN_NAME', 'COLUMN_DEFAULT', 'DATA_TYPE', 'IS_NULLABLE', 'CHARACTER_MAXIMUM_LENGTH') - .orderBy('ORDINAL_POSITION') - .where({ - table_catalog: database, - table_name: tableName, - table_schema: schema, - }); - - let generatedColumns = await knex.raw( - `select COLUMN_NAME + const result = await knex.raw(query, [this.connection.database, this.connection.database]); + + return result.map(({ TABLE_NAME, isView }: { TABLE_NAME: string; isView: number }) => ({ + tableName: TABLE_NAME, + isView: isView === 1, + })); + } + + public async getTableStructure(tableName: string): Promise { + const cachedTableStructure = LRUStorage.getTableStructureCache(this.connection, tableName); + if (cachedTableStructure) { + return cachedTableStructure; + } + const { database } = this.connection; + const knex = await this.configureKnex(); + const schema = await this.getSchemaNameWithoutBrackets(tableName); + const structureColumns = await knex('information_schema.COLUMNS') + .select('COLUMN_NAME', 'COLUMN_DEFAULT', 'DATA_TYPE', 'IS_NULLABLE', 'CHARACTER_MAXIMUM_LENGTH') + .orderBy('ORDINAL_POSITION') + .where({ + table_catalog: database, + table_name: tableName, + table_schema: schema, + }); + + let generatedColumns = await knex.raw( + `select COLUMN_NAME from INFORMATION_SCHEMA.COLUMNS where COLUMNPROPERTY(object_id(TABLE_SCHEMA + '.' + TABLE_NAME), COLUMN_NAME, 'IsIdentity') = 1 AND TABLE_CATALOG = ? AND TABLE_NAME = ? AND TABLE_SCHEMA = ?`, - [database, tableName, schema], - ); - - generatedColumns = generatedColumns.map((column) => column.COLUMN_NAME); - - const structureColumnsInLowercase = structureColumns.map(objectKeysToLowercase); - - structureColumnsInLowercase.map((column) => { - renameObjectKeyName(column, 'is_nullable', 'allow_null'); - column.allow_null = column.allow_null === 'YES'; - if (generatedColumns.indexOf(column.column_name) >= 0) { - column.column_default = 'autoincrement'; - } - return column; - }); - LRUStorage.setTableStructureCache(this.connection, tableName, structureColumnsInLowercase as TableStructureDS[]); - return structureColumnsInLowercase as TableStructureDS[]; - } - - public async testConnect(): Promise { - if (!this.connection.id) { - this.connection.id = nanoid(6); - } - const knex = await this.configureKnex(); - try { - await knex.queryBuilder().select(1); - return { - result: true, - message: 'Successfully connected', - }; - } catch (e) { - return { - result: false, - message: e.message || 'Connection failed', - }; - } finally { - LRUStorage.delKnexCache(this.connection); - } - } - - public async updateRowInTable( - tableName: string, - row: Record, - primaryKey: Record, - ): Promise> { - const [knex, schemaName] = await Promise.all([this.configureKnex(), this.getSchemaName(tableName)]); - const tableWithSchema = `${schemaName}.[${tableName}]`; - return knex(tableWithSchema).returning(Object.keys(primaryKey)).where(primaryKey).update(row); - } - - public async bulkUpdateRowsInTable( - tableName: string, - newValues: Record, - primaryKeys: Array>, - ): Promise>> { - const [knex, schemaName] = await Promise.all([this.configureKnex(), this.getSchemaName(tableName)]); - const tableWithSchema = `${schemaName}.[${tableName}]`; - - return await knex.transaction(async (trx) => { - const results = []; - for (const primaryKey of primaryKeys) { - const result = await trx(tableWithSchema) - .returning(Object.keys(primaryKey)) - .where(primaryKey) - .update(newValues); - results.push(result[0]); - } - return results; - }); - } - - public async bulkDeleteRowsInTable(tableName: string, primaryKeys: Array>): Promise { - const [knex, schemaName] = await Promise.all([this.configureKnex(), this.getSchemaName(tableName)]); - const tableWithSchema = `${schemaName}.[${tableName}]`; - - if (primaryKeys.length === 0) { - return 0; - } - - await knex.transaction(async (trx) => { - await trx(tableWithSchema) - .delete() - .modify((queryBuilder) => { - primaryKeys.forEach((key) => { - queryBuilder.orWhere((builder) => { - Object.entries(key).forEach(([column, value]) => { - builder.andWhere(column, value); - }); - }); - }); - }); - }); - - return primaryKeys.length; - } - - public async validateSettings(settings: ValidateTableSettingsDS, tableName: string): Promise { - const [tableStructure, primaryColumns] = await Promise.all([ - this.getTableStructure(tableName), - this.getTablePrimaryColumns(tableName), - ]); - return tableSettingsFieldValidator(tableStructure, primaryColumns, settings); - } - - public async getReferencedTableNamesAndColumns(tableName: string): Promise { - const primaryColumns = await this.getTablePrimaryColumns(tableName); - const knex = await this.configureKnex(); - - const queries = primaryColumns.map((primaryColumn) => - knex - .raw( - ` + [database, tableName, schema], + ); + + generatedColumns = generatedColumns.map((column) => column.COLUMN_NAME); + + const structureColumnsInLowercase = structureColumns.map(objectKeysToLowercase); + + structureColumnsInLowercase.map((column) => { + renameObjectKeyName(column, 'is_nullable', 'allow_null'); + column.allow_null = column.allow_null === 'YES'; + if (generatedColumns.indexOf(column.column_name) >= 0) { + column.column_default = 'autoincrement'; + } + return column; + }); + LRUStorage.setTableStructureCache(this.connection, tableName, structureColumnsInLowercase as TableStructureDS[]); + return structureColumnsInLowercase as TableStructureDS[]; + } + + public async testConnect(): Promise { + if (!this.connection.id) { + this.connection.id = nanoid(6); + } + const knex = await this.configureKnex(); + try { + await knex.queryBuilder().select(1); + return { + result: true, + message: 'Successfully connected', + }; + } catch (e) { + return { + result: false, + message: e.message || 'Connection failed', + }; + } finally { + LRUStorage.delKnexCache(this.connection); + } + } + + public async updateRowInTable( + tableName: string, + row: Record, + primaryKey: Record, + ): Promise> { + const [knex, schemaName] = await Promise.all([this.configureKnex(), this.getSchemaName(tableName)]); + const tableWithSchema = `${schemaName}.[${tableName}]`; + return knex(tableWithSchema).returning(Object.keys(primaryKey)).where(primaryKey).update(row); + } + + public async bulkUpdateRowsInTable( + tableName: string, + newValues: Record, + primaryKeys: Array>, + ): Promise>> { + const [knex, schemaName] = await Promise.all([this.configureKnex(), this.getSchemaName(tableName)]); + const tableWithSchema = `${schemaName}.[${tableName}]`; + + return await knex.transaction(async (trx) => { + const results = []; + for (const primaryKey of primaryKeys) { + const result = await trx(tableWithSchema) + .returning(Object.keys(primaryKey)) + .where(primaryKey) + .update(newValues); + results.push(result[0]); + } + return results; + }); + } + + public async bulkDeleteRowsInTable(tableName: string, primaryKeys: Array>): Promise { + const [knex, schemaName] = await Promise.all([this.configureKnex(), this.getSchemaName(tableName)]); + const tableWithSchema = `${schemaName}.[${tableName}]`; + + if (primaryKeys.length === 0) { + return 0; + } + + await knex.transaction(async (trx) => { + await trx(tableWithSchema) + .delete() + .modify((queryBuilder) => { + primaryKeys.forEach((key) => { + queryBuilder.orWhere((builder) => { + Object.entries(key).forEach(([column, value]) => { + builder.andWhere(column, value); + }); + }); + }); + }); + }); + + return primaryKeys.length; + } + + public async validateSettings(settings: ValidateTableSettingsDS, tableName: string): Promise { + const [tableStructure, primaryColumns] = await Promise.all([ + this.getTableStructure(tableName), + this.getTablePrimaryColumns(tableName), + ]); + return tableSettingsFieldValidator(tableStructure, primaryColumns, settings); + } + + public async getReferencedTableNamesAndColumns(tableName: string): Promise { + const primaryColumns = await this.getTablePrimaryColumns(tableName); + const knex = await this.configureKnex(); + + const queries = primaryColumns.map((primaryColumn) => + knex + .raw( + ` SELECT OBJECT_NAME(f.parent_object_id) "table_name", COL_NAME(fc.parent_object_id,fc.parent_column_id) "column_name" @@ -482,171 +481,171 @@ WHERE TABLE_TYPE = 'VIEW' WHERE OBJECT_NAME (f.referenced_object_id) = ? `, - tableName, - ) - .then((result) => { - let resultValue = result[0] || []; - resultValue = Array.isArray(resultValue) ? resultValue : [resultValue]; - return { - referenced_on_column_name: primaryColumn.column_name, - referenced_by: resultValue, - }; - }), - ); - - return Promise.all(queries); - } - - public async isView(tableName: string): Promise { - const knex = await this.configureKnex(); - const schemaName = await this.getSchemaNameWithoutBrackets(tableName); - const result = await knex('information_schema.tables') - .select('TABLE_TYPE') - .where('TABLE_SCHEMA', schemaName) - .andWhere('TABLE_NAME', tableName); - - if (result.length === 0) { - throw new Error(ERROR_MESSAGES.TABLE_NOT_FOUND(tableName)); - } - return result[0].TABLE_TYPE === 'VIEW'; - } - - public async getTableRowsStream( - tableName: string, - tableSettings: TableSettingsDS, - page: number, - perPage: number, - searchedFieldValue: string, - filteringFields: Array, - ): Promise> { - page = page > 0 ? page : DAO_CONSTANTS.DEFAULT_PAGINATION.page; - perPage = - perPage > 0 - ? perPage - : tableSettings.list_per_page > 0 - ? tableSettings.list_per_page - : DAO_CONSTANTS.DEFAULT_PAGINATION.perPage; - - const knex = await this.configureKnex(); - const [tableStructure, tableSchema] = await Promise.all([ - this.getTableStructure(tableName), - this.getSchemaName(tableName), - ]); - - const availableFields = this.findAvailableFields(tableSettings, tableStructure); - - // if (rowsCount >= DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT) { - // throw new Error(ERROR_MESSAGES.DATA_IS_TO_LARGE); - // } - - if (tableSchema) { - tableName = `${tableSchema}.[${tableName}]`; - } - - tableSettings.ordering_field = tableSettings?.ordering_field || availableFields[0]; - tableSettings.ordering = tableSettings?.ordering || QueryOrderingEnum.ASC; - - const { ordering_field, ordering } = tableSettings; - const offset = (page - 1) * perPage; - - const rowsAsStream = knex(tableName) - .modify((builder) => { - let search_fields = tableSettings?.search_fields || []; - - if (search_fields.length === 0 && searchedFieldValue) { - search_fields = availableFields; - } - - if (searchedFieldValue) { - search_fields.forEach((field) => { - if (Buffer.isBuffer(searchedFieldValue)) { - builder.orWhere(field, '=', searchedFieldValue); - } else { - builder.orWhereRaw(`LOWER(CAST(?? AS CHAR(255))) LIKE ?`, [ - field, - `${searchedFieldValue.toLowerCase()}%`, - ]); - } - }); - } - }) - .modify((builder) => { - if (filteringFields?.length > 0) { - for (const { field, criteria, value } of filteringFields) { - const operators = { - [FilterCriteriaEnum.eq]: '=', - [FilterCriteriaEnum.startswith]: 'like', - [FilterCriteriaEnum.endswith]: 'like', - [FilterCriteriaEnum.gt]: '>', - [FilterCriteriaEnum.lt]: '<', - [FilterCriteriaEnum.lte]: '<=', - [FilterCriteriaEnum.gte]: '>=', - [FilterCriteriaEnum.contains]: 'like', - [FilterCriteriaEnum.icontains]: 'not like', - [FilterCriteriaEnum.empty]: 'is', - }; - - const values = { - [FilterCriteriaEnum.startswith]: `${value}%`, - [FilterCriteriaEnum.endswith]: `%${value}`, - [FilterCriteriaEnum.contains]: `%${value}%`, - [FilterCriteriaEnum.icontains]: `%${value}%`, - [FilterCriteriaEnum.empty]: null, - }; - builder.where(field, operators[criteria], values[criteria] || value); - } - } - }) - .orderBy(ordering_field, ordering) - .limit(perPage) - .offset(offset) - .stream(); - return rowsAsStream; - } - - public async importCSVInTable(file: Express.Multer.File, tableName: string): Promise { - const [knex, schemaName] = await Promise.all([this.configureKnex(), this.getSchemaName(tableName)]); - const tableWithSchema = `${schemaName}.[${tableName}]`; - const structure = await this.getTableStructure(tableName); - const timestampColumnNames = structure - .filter(({ data_type }) => isMSSQLDateOrTimeType(data_type)) - .map(({ column_name }) => column_name); - const stream = new Readable(); - stream.push(file.buffer); - stream.push(null); - - const parser = stream.pipe(csv.parse({ columns: true })); - - const results: any[] = []; - for await (const record of parser) { - results.push(record); - } - await knex.transaction(async (trx) => { - for (const row of results) { - for (const column of timestampColumnNames) { - if (row[column] && !isMSSQLDateStringByRegexp(row[column])) { - const date = new Date(Number(row[column])); - row[column] = date.toISOString(); - } - } - - await trx(tableWithSchema).insert(row); - } - }); - } - - public async executeRawQuery(query: string): Promise>> { - const knex = await this.configureKnex(); - return await knex.raw(query); - } - - private async getSchemaName(tableName: string): Promise { - if (this.connection.schema) { - return `[${this.connection.schema}]`; - } - const knex = await this.configureKnex(); - const queryResult = - await knex.raw(`SELECT QUOTENAME(SCHEMA_NAME(sOBJ.schema_id)) + '.' + QUOTENAME(sOBJ.name) AS [TableName] + tableName, + ) + .then((result) => { + let resultValue = result[0] || []; + resultValue = Array.isArray(resultValue) ? resultValue : [resultValue]; + return { + referenced_on_column_name: primaryColumn.column_name, + referenced_by: resultValue, + }; + }), + ); + + return Promise.all(queries); + } + + public async isView(tableName: string): Promise { + const knex = await this.configureKnex(); + const schemaName = await this.getSchemaNameWithoutBrackets(tableName); + const result = await knex('information_schema.tables') + .select('TABLE_TYPE') + .where('TABLE_SCHEMA', schemaName) + .andWhere('TABLE_NAME', tableName); + + if (result.length === 0) { + throw new Error(ERROR_MESSAGES.TABLE_NOT_FOUND(tableName)); + } + return result[0].TABLE_TYPE === 'VIEW'; + } + + public async getTableRowsStream( + tableName: string, + tableSettings: TableSettingsDS, + page: number, + perPage: number, + searchedFieldValue: string, + filteringFields: Array, + ): Promise> { + page = page > 0 ? page : DAO_CONSTANTS.DEFAULT_PAGINATION.page; + perPage = + perPage > 0 + ? perPage + : tableSettings.list_per_page > 0 + ? tableSettings.list_per_page + : DAO_CONSTANTS.DEFAULT_PAGINATION.perPage; + + const knex = await this.configureKnex(); + const [tableStructure, tableSchema] = await Promise.all([ + this.getTableStructure(tableName), + this.getSchemaName(tableName), + ]); + + const availableFields = this.findAvailableFields(tableSettings, tableStructure); + + // if (rowsCount >= DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT) { + // throw new Error(ERROR_MESSAGES.DATA_IS_TO_LARGE); + // } + + if (tableSchema) { + tableName = `${tableSchema}.[${tableName}]`; + } + + tableSettings.ordering_field = tableSettings?.ordering_field || availableFields[0]; + tableSettings.ordering = tableSettings?.ordering || QueryOrderingEnum.ASC; + + const { ordering_field, ordering } = tableSettings; + const offset = (page - 1) * perPage; + + const rowsAsStream = knex(tableName) + .modify((builder) => { + let search_fields = tableSettings?.search_fields || []; + + if (search_fields.length === 0 && searchedFieldValue) { + search_fields = availableFields; + } + + if (searchedFieldValue) { + search_fields.forEach((field) => { + if (Buffer.isBuffer(searchedFieldValue)) { + builder.orWhere(field, '=', searchedFieldValue); + } else { + builder.orWhereRaw(`LOWER(CAST(?? AS CHAR(255))) LIKE ?`, [ + field, + `${searchedFieldValue.toLowerCase()}%`, + ]); + } + }); + } + }) + .modify((builder) => { + if (filteringFields?.length > 0) { + for (const { field, criteria, value } of filteringFields) { + const operators = { + [FilterCriteriaEnum.eq]: '=', + [FilterCriteriaEnum.startswith]: 'like', + [FilterCriteriaEnum.endswith]: 'like', + [FilterCriteriaEnum.gt]: '>', + [FilterCriteriaEnum.lt]: '<', + [FilterCriteriaEnum.lte]: '<=', + [FilterCriteriaEnum.gte]: '>=', + [FilterCriteriaEnum.contains]: 'like', + [FilterCriteriaEnum.icontains]: 'not like', + [FilterCriteriaEnum.empty]: 'is', + }; + + const values = { + [FilterCriteriaEnum.startswith]: `${value}%`, + [FilterCriteriaEnum.endswith]: `%${value}`, + [FilterCriteriaEnum.contains]: `%${value}%`, + [FilterCriteriaEnum.icontains]: `%${value}%`, + [FilterCriteriaEnum.empty]: null, + }; + builder.where(field, operators[criteria], values[criteria] || value); + } + } + }) + .orderBy(ordering_field, ordering) + .limit(perPage) + .offset(offset) + .stream(); + return rowsAsStream; + } + + public async importCSVInTable(file: Express.Multer.File, tableName: string): Promise { + const [knex, schemaName] = await Promise.all([this.configureKnex(), this.getSchemaName(tableName)]); + const tableWithSchema = `${schemaName}.[${tableName}]`; + const structure = await this.getTableStructure(tableName); + const timestampColumnNames = structure + .filter(({ data_type }) => isMSSQLDateOrTimeType(data_type)) + .map(({ column_name }) => column_name); + const stream = new Readable(); + stream.push(file.buffer); + stream.push(null); + + const parser = stream.pipe(csv.parse({ columns: true })); + + const results: any[] = []; + for await (const record of parser) { + results.push(record); + } + await knex.transaction(async (trx) => { + for (const row of results) { + for (const column of timestampColumnNames) { + if (row[column] && !isMSSQLDateStringByRegexp(row[column])) { + const date = new Date(Number(row[column])); + row[column] = date.toISOString(); + } + } + + await trx(tableWithSchema).insert(row); + } + }); + } + + public async executeRawQuery(query: string): Promise>> { + const knex = await this.configureKnex(); + return await knex.raw(query); + } + + private async getSchemaName(tableName: string): Promise { + if (this.connection.schema) { + return `[${this.connection.schema}]`; + } + const knex = await this.configureKnex(); + const queryResult = + await knex.raw(`SELECT QUOTENAME(SCHEMA_NAME(sOBJ.schema_id)) + '.' + QUOTENAME(sOBJ.name) AS [TableName] , SUM(sdmvPTNS.row_count) AS [RowCount] FROM sys.objects AS sOBJ @@ -662,69 +661,69 @@ WHERE TABLE_TYPE = 'VIEW' , sOBJ.name ORDER BY [TableName]`); - const row = queryResult.find((row: any) => row.TableName.includes(tableName)); - return row ? row.TableName.split('.')[0] : undefined; - } - - private async getRowsCount(tableName: string, countRowsQB: Knex.QueryBuilder | null): Promise { - if (countRowsQB) { - const slowRowsCount = await this.getRowsCountByQueryWithTimeOut(countRowsQB); - if (slowRowsCount) { - return slowRowsCount; - } - return await this.getFastRowsCount(tableName); - } - - const fastRowsCount = await this.getFastRowsCount(tableName); - if (fastRowsCount >= DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT) { - return fastRowsCount; - } - - const knex = await this.configureKnex(); - const countRows = knex(tableName).count('*'); - const slowRowsCount = await this.getRowsCountByQuery(countRows); - return slowRowsCount || fastRowsCount; - } - - private async getSchemaNameWithoutBrackets(tableName: string): Promise { - const schema = await this.getSchemaName(tableName); - if (!schema) { - throw new Error(ERROR_MESSAGES.TABLE_SCHEMA_NOT_FOUND(tableName)); - } - const matches = schema.match(/\[(.*?)\]/); - return matches[1]; - } - - private async getRowsCountByQueryWithTimeOut(countRowsQB: Knex.QueryBuilder): Promise { - return new Promise(async (resolve) => { - setTimeout(() => { - resolve(null); - }, DAO_CONSTANTS.COUNT_QUERY_TIMEOUT_MS); - - try { - const slowRowsCountQueryResult = await countRowsQB.count('*'); - const slowRowsCount = Object.values(slowRowsCountQueryResult[0])[0]; - resolve(slowRowsCount as number); - } catch (_e) { - resolve(null); - } - }); - } - - private async getRowsCountByQuery(countRowsQB: Knex.QueryBuilder): Promise { - try { - const slowRowsCountQueryResult = await countRowsQB.count('*'); - const slowRowsCount = Object.values(slowRowsCountQueryResult[0])[0]; - return slowRowsCount as number; - } catch (_error) { - return null; - } - } - - private async getFastRowsCount(tableName: string): Promise { - const knex = await this.configureKnex(); - const fastCountQueryResult = await knex.raw( - `SELECT QUOTENAME(SCHEMA_NAME(sOBJ.schema_id)) + '.' + QUOTENAME(sOBJ.name) AS [TableName] + const row = queryResult.find((row: any) => row.TableName.includes(tableName)); + return row ? row.TableName.split('.')[0] : undefined; + } + + private async getRowsCount(tableName: string, countRowsQB: Knex.QueryBuilder | null): Promise { + if (countRowsQB) { + const slowRowsCount = await this.getRowsCountByQueryWithTimeOut(countRowsQB); + if (slowRowsCount) { + return slowRowsCount; + } + return await this.getFastRowsCount(tableName); + } + + const fastRowsCount = await this.getFastRowsCount(tableName); + if (fastRowsCount >= DAO_CONSTANTS.LARGE_DATASET_ROW_LIMIT) { + return fastRowsCount; + } + + const knex = await this.configureKnex(); + const countRows = knex(tableName).count('*'); + const slowRowsCount = await this.getRowsCountByQuery(countRows); + return slowRowsCount || fastRowsCount; + } + + private async getSchemaNameWithoutBrackets(tableName: string): Promise { + const schema = await this.getSchemaName(tableName); + if (!schema) { + throw new Error(ERROR_MESSAGES.TABLE_SCHEMA_NOT_FOUND(tableName)); + } + const matches = schema.match(/\[(.*?)\]/); + return matches[1]; + } + + private async getRowsCountByQueryWithTimeOut(countRowsQB: Knex.QueryBuilder): Promise { + return new Promise(async (resolve) => { + setTimeout(() => { + resolve(null); + }, DAO_CONSTANTS.COUNT_QUERY_TIMEOUT_MS); + + try { + const slowRowsCountQueryResult = await countRowsQB.count('*'); + const slowRowsCount = Object.values(slowRowsCountQueryResult[0])[0]; + resolve(slowRowsCount as number); + } catch (_e) { + resolve(null); + } + }); + } + + private async getRowsCountByQuery(countRowsQB: Knex.QueryBuilder): Promise { + try { + const slowRowsCountQueryResult = await countRowsQB.count('*'); + const slowRowsCount = Object.values(slowRowsCountQueryResult[0])[0]; + return slowRowsCount as number; + } catch (_error) { + return null; + } + } + + private async getFastRowsCount(tableName: string): Promise { + const knex = await this.configureKnex(); + const fastCountQueryResult = await knex.raw( + `SELECT QUOTENAME(SCHEMA_NAME(sOBJ.schema_id)) + '.' + QUOTENAME(sOBJ.name) AS [TableName] , SUM(sdmvPTNS.row_count) AS [RowCount] FROM sys.objects AS sOBJ @@ -740,8 +739,8 @@ WHERE TABLE_TYPE = 'VIEW' sOBJ.schema_id , sOBJ.name ORDER BY [TableName]`, - [tableName], - ); - return parseInt(fastCountQueryResult[0].RowCount, 10); - } + [tableName], + ); + return parseInt(fastCountQueryResult[0].RowCount, 10); + } } diff --git a/shared-code/src/data-access-layer/shared/create-data-access-object.ts b/shared-code/src/data-access-layer/shared/create-data-access-object.ts index b0abedf0c..99bee6bdb 100644 --- a/shared-code/src/data-access-layer/shared/create-data-access-object.ts +++ b/shared-code/src/data-access-layer/shared/create-data-access-object.ts @@ -17,164 +17,164 @@ import { IDataAccessObjectAgent } from '../../shared/interfaces/data-access-obje import { IDataAccessObject } from '../../shared/interfaces/data-access-object.interface.js'; interface IUnknownConnectionParams { - [key: string]: any; + [key: string]: any; } export function getDataAccessObject( - connectionParams: IUnknownConnectionParams, + connectionParams: IUnknownConnectionParams, ): IDataAccessObject | IDataAccessObjectAgent { - const agentTypes = [ - ConnectionTypesEnum.agent_mssql, - ConnectionTypesEnum.agent_mysql, - ConnectionTypesEnum.agent_oracledb, - ConnectionTypesEnum.agent_postgres, - ConnectionTypesEnum.agent_ibmdb2, - ConnectionTypesEnum.agent_mongodb, - ConnectionTypesEnum.agent_cassandra, - ConnectionTypesEnum.agent_redis, - ConnectionTypesEnum.agent_clickhouse, - ]; - if (!connectionParams || connectionParams === null) { - throw new Error(ERROR_MESSAGES.CONNECTION_PARAMS_SHOULD_BE_DEFINED); - } - if (!connectionParams.type) { - throw new Error(ERROR_MESSAGES.PROPERTY_TYPE_REQUIRED); - } - switch (connectionParams.type) { - case ConnectionTypesEnum.postgres: { - const connectionParamsPostgres = buildConnectionParams(connectionParams); - return new DataAccessObjectPostgres(connectionParamsPostgres); - } - case ConnectionTypesEnum.mysql: { - const connectionParamsMysql = buildConnectionParams(connectionParams); - return new DataAccessObjectMysql(connectionParamsMysql); - } - case ConnectionTypesEnum.mssql: { - const connectionParamsMssql = buildConnectionParams(connectionParams); - return new DataAccessObjectMssql(connectionParamsMssql); - } - case ConnectionTypesEnum.oracledb: { - const connectionParamsOracle = buildConnectionParams(connectionParams); - return new DataAccessObjectOracle(connectionParamsOracle); - } - case ConnectionTypesEnum.ibmdb2: { - const connectionParamsToIbmDB2 = buildConnectionParams(connectionParams); - return new DataAccessObjectIbmDb2(connectionParamsToIbmDB2); - } - case ConnectionTypesEnum.mongodb: { - const connectionParamsMongo = buildConnectionParams(connectionParams); - return new DataAccessObjectMongo(connectionParamsMongo); - } - case ConnectionTypesEnum.dynamodb: { - const connectionParamsDynamoDB = buildConnectionParams(connectionParams); - return new DataAccessObjectDynamoDB(connectionParamsDynamoDB); - } - case ConnectionTypesEnum.elasticsearch: { - const connectionParamsElasticsearch = buildConnectionParams(connectionParams); - return new DataAccessObjectElasticsearch(connectionParamsElasticsearch); - } - case ConnectionTypesEnum.cassandra: { - const connectionParamsCassandra = buildConnectionParams(connectionParams); - return new DataAccessObjectCassandra(connectionParamsCassandra); - } - case ConnectionTypesEnum.redis: { - const connectionParamsRedis = buildConnectionParams(connectionParams); - return new DataAccessObjectRedis(connectionParamsRedis); - } - case ConnectionTypesEnum.clickhouse: { - const connectionParamsClickHouse = buildConnectionParams(connectionParams); - return new DataAccessObjectClickHouse(connectionParamsClickHouse); - } - default: { - if (!agentTypes.includes(connectionParams.type)) { - throw new Error(ERROR_MESSAGES.CONNECTION_TYPE_INVALID); - } - const connectionParamsAgent = buildAgentConnectionParams(connectionParams); - return new DataAccessObjectAgent(connectionParamsAgent); - } - } + const agentTypes = [ + ConnectionTypesEnum.agent_mssql, + ConnectionTypesEnum.agent_mysql, + ConnectionTypesEnum.agent_oracledb, + ConnectionTypesEnum.agent_postgres, + ConnectionTypesEnum.agent_ibmdb2, + ConnectionTypesEnum.agent_mongodb, + ConnectionTypesEnum.agent_cassandra, + ConnectionTypesEnum.agent_redis, + ConnectionTypesEnum.agent_clickhouse, + ]; + if (!connectionParams || connectionParams === null) { + throw new Error(ERROR_MESSAGES.CONNECTION_PARAMS_SHOULD_BE_DEFINED); + } + if (!connectionParams.type) { + throw new Error(ERROR_MESSAGES.PROPERTY_TYPE_REQUIRED); + } + switch (connectionParams.type) { + case ConnectionTypesEnum.postgres: { + const connectionParamsPostgres = buildConnectionParams(connectionParams); + return new DataAccessObjectPostgres(connectionParamsPostgres); + } + case ConnectionTypesEnum.mysql: { + const connectionParamsMysql = buildConnectionParams(connectionParams); + return new DataAccessObjectMysql(connectionParamsMysql); + } + case ConnectionTypesEnum.mssql: { + const connectionParamsMssql = buildConnectionParams(connectionParams); + return new DataAccessObjectMssql(connectionParamsMssql); + } + case ConnectionTypesEnum.oracledb: { + const connectionParamsOracle = buildConnectionParams(connectionParams); + return new DataAccessObjectOracle(connectionParamsOracle); + } + case ConnectionTypesEnum.ibmdb2: { + const connectionParamsToIbmDB2 = buildConnectionParams(connectionParams); + return new DataAccessObjectIbmDb2(connectionParamsToIbmDB2); + } + case ConnectionTypesEnum.mongodb: { + const connectionParamsMongo = buildConnectionParams(connectionParams); + return new DataAccessObjectMongo(connectionParamsMongo); + } + case ConnectionTypesEnum.dynamodb: { + const connectionParamsDynamoDB = buildConnectionParams(connectionParams); + return new DataAccessObjectDynamoDB(connectionParamsDynamoDB); + } + case ConnectionTypesEnum.elasticsearch: { + const connectionParamsElasticsearch = buildConnectionParams(connectionParams); + return new DataAccessObjectElasticsearch(connectionParamsElasticsearch); + } + case ConnectionTypesEnum.cassandra: { + const connectionParamsCassandra = buildConnectionParams(connectionParams); + return new DataAccessObjectCassandra(connectionParamsCassandra); + } + case ConnectionTypesEnum.redis: { + const connectionParamsRedis = buildConnectionParams(connectionParams); + return new DataAccessObjectRedis(connectionParamsRedis); + } + case ConnectionTypesEnum.clickhouse: { + const connectionParamsClickHouse = buildConnectionParams(connectionParams); + return new DataAccessObjectClickHouse(connectionParamsClickHouse); + } + default: { + if (!agentTypes.includes(connectionParams.type)) { + throw new Error(ERROR_MESSAGES.CONNECTION_TYPE_INVALID); + } + const connectionParamsAgent = buildAgentConnectionParams(connectionParams); + return new DataAccessObjectAgent(connectionParamsAgent); + } + } } function buildAgentConnectionParams(connectionParams: IUnknownConnectionParams): ConnectionAgentParams { - if (!connectionParams.agent || !connectionParams.agent.token) { - throw new Error(ERROR_MESSAGES.AGENT_SHOULD_BE_DEFINED); - } - return { - id: connectionParams.id || null, - title: connectionParams.title || null, - signing_key: connectionParams.signing_key, - token: connectionParams.agent.token, - type: connectionParams.type, - isTestConnection: false, - }; + if (!connectionParams.agent || !connectionParams.agent.token) { + throw new Error(ERROR_MESSAGES.AGENT_SHOULD_BE_DEFINED); + } + return { + id: connectionParams.id || null, + title: connectionParams.title || null, + signing_key: connectionParams.signing_key, + token: connectionParams.agent.token, + type: connectionParams.type, + isTestConnection: false, + }; } function buildConnectionParams(connectionParams: IUnknownConnectionParams): ConnectionParams { - const requiredKeys = []; + const requiredKeys = []; - const sqlAndMongoRequiredKeys = ['type', 'host', 'port', 'username', 'password', 'database']; - const elasticAndDynamoAndRedisRequiredKeys = ['host', 'username', 'password']; - const redisRequiredKeys = !isRedisConnectionUrl(connectionParams.host) ? ['host', 'port', 'password'] : ['host']; + const sqlAndMongoRequiredKeys = ['type', 'host', 'port', 'username', 'password', 'database']; + const elasticAndDynamoAndRedisRequiredKeys = ['host', 'username', 'password']; + const redisRequiredKeys = !isRedisConnectionUrl(connectionParams.host) ? ['host', 'port', 'password'] : ['host']; - switch (connectionParams.type) { - case ConnectionTypesEnum.postgres: - case ConnectionTypesEnum.mysql2: - case ConnectionTypesEnum.mysql: - case ConnectionTypesEnum.mssql: - case ConnectionTypesEnum.oracledb: - case ConnectionTypesEnum.ibmdb2: - case ConnectionTypesEnum.mongodb: - case ConnectionTypesEnum.cassandra: - case ConnectionTypesEnum.clickhouse: - requiredKeys.push(...sqlAndMongoRequiredKeys); - break; - case ConnectionTypesEnum.dynamodb: - case ConnectionTypesEnum.elasticsearch: - requiredKeys.push(...elasticAndDynamoAndRedisRequiredKeys); - break; - case ConnectionTypesEnum.redis: - requiredKeys.push(...redisRequiredKeys); - break; - default: - throw new Error(ERROR_MESSAGES.CONNECTION_TYPE_INVALID); - } + switch (connectionParams.type) { + case ConnectionTypesEnum.postgres: + case ConnectionTypesEnum.mysql2: + case ConnectionTypesEnum.mysql: + case ConnectionTypesEnum.mssql: + case ConnectionTypesEnum.oracledb: + case ConnectionTypesEnum.ibmdb2: + case ConnectionTypesEnum.mongodb: + case ConnectionTypesEnum.cassandra: + case ConnectionTypesEnum.clickhouse: + requiredKeys.push(...sqlAndMongoRequiredKeys); + break; + case ConnectionTypesEnum.dynamodb: + case ConnectionTypesEnum.elasticsearch: + requiredKeys.push(...elasticAndDynamoAndRedisRequiredKeys); + break; + case ConnectionTypesEnum.redis: + requiredKeys.push(...redisRequiredKeys); + break; + default: + throw new Error(ERROR_MESSAGES.CONNECTION_TYPE_INVALID); + } - if (connectionParams.ssh) { - requiredKeys.push('sshHost', 'sshPort', 'sshUsername'); - } + if (connectionParams.ssh) { + requiredKeys.push('sshHost', 'sshPort', 'sshUsername'); + } - // eslint-disable-next-line security/detect-object-injection - const missingKeys = requiredKeys.filter((key) => !connectionParams[key]); - if (missingKeys.length > 0) { - throw new Error(`Missing required key${missingKeys.length > 1 ? 's' : ''}: ${missingKeys.join(', ')}`); - } - const connection = { - id: connectionParams.id, - title: connectionParams.title, - type: connectionParams.type === ConnectionTypesEnum.mysql ? 'mysql2' : connectionParams.type, - host: connectionParams.host, - port: connectionParams.port, - username: connectionParams.username, - password: connectionParams.password, - database: connectionParams.database, - schema: connectionParams.schema || null, - sid: connectionParams.sid || null, - ssh: connectionParams.ssh, - privateSSHKey: connectionParams.privateSSHKey || null, - sshHost: connectionParams.sshHost || null, - sshPort: connectionParams.sshPort || null, - sshUsername: connectionParams.sshUsername || null, - ssl: connectionParams.ssl || false, - cert: connectionParams.cert || null, - azure_encryption: connectionParams.azure_encryption || false, - signing_key: connectionParams.signing_key || null, - authSource: connectionParams.authSource || null, - dataCenter: connectionParams.dataCenter || null, - isTestConnection: connectionParams.isTestConnection || false, - }; - return connection; + // eslint-disable-next-line security/detect-object-injection + const missingKeys = requiredKeys.filter((key) => !connectionParams[key]); + if (missingKeys.length > 0) { + throw new Error(`Missing required key${missingKeys.length > 1 ? 's' : ''}: ${missingKeys.join(', ')}`); + } + const connection = { + id: connectionParams.id, + title: connectionParams.title, + type: connectionParams.type === ConnectionTypesEnum.mysql ? 'mysql2' : connectionParams.type, + host: connectionParams.host, + port: connectionParams.port, + username: connectionParams.username, + password: connectionParams.password, + database: connectionParams.database, + schema: connectionParams.schema || null, + sid: connectionParams.sid || null, + ssh: connectionParams.ssh, + privateSSHKey: connectionParams.privateSSHKey || null, + sshHost: connectionParams.sshHost || null, + sshPort: connectionParams.sshPort || null, + sshUsername: connectionParams.sshUsername || null, + ssl: connectionParams.ssl || false, + cert: connectionParams.cert || null, + azure_encryption: connectionParams.azure_encryption || false, + signing_key: connectionParams.signing_key || null, + authSource: connectionParams.authSource || null, + dataCenter: connectionParams.dataCenter || null, + isTestConnection: connectionParams.isTestConnection || false, + }; + return connection; } export function isRedisConnectionUrl(host: string): boolean { - const redisUrlPattern = /^rediss?:\/\/.+/i; - return redisUrlPattern.test(host); + const redisUrlPattern = /^rediss?:\/\/.+/i; + return redisUrlPattern.test(host); } diff --git a/shared-code/src/data-access-layer/shared/data-structures/autocomplete-fields.ds.ts b/shared-code/src/data-access-layer/shared/data-structures/autocomplete-fields.ds.ts index 8e3c2ca5b..7ca466569 100644 --- a/shared-code/src/data-access-layer/shared/data-structures/autocomplete-fields.ds.ts +++ b/shared-code/src/data-access-layer/shared/data-structures/autocomplete-fields.ds.ts @@ -1,4 +1,4 @@ export class AutocompleteFieldsDS { - fields: Array; - value: unknown; + fields: Array; + value: unknown; } diff --git a/shared-code/src/data-access-layer/shared/data-structures/connections-params.ds.ts b/shared-code/src/data-access-layer/shared/data-structures/connections-params.ds.ts index 074b21a61..476abe7f8 100644 --- a/shared-code/src/data-access-layer/shared/data-structures/connections-params.ds.ts +++ b/shared-code/src/data-access-layer/shared/data-structures/connections-params.ds.ts @@ -1,65 +1,65 @@ export class ConnectionParams { - id: string; + id: string; - title: string | null; + title: string | null; - type: - | 'postgres' - | 'oracledb' - | 'mysql2' - | 'mssql' - | 'ibmdb2' - | 'mongodb' - | 'dynamodb' - | 'elasticsearch' - | 'cassandra' - | 'redis' - | 'clickhouse'; + type: + | 'postgres' + | 'oracledb' + | 'mysql2' + | 'mssql' + | 'ibmdb2' + | 'mongodb' + | 'dynamodb' + | 'elasticsearch' + | 'cassandra' + | 'redis' + | 'clickhouse'; - host: string; + host: string; - port: number; + port: number; - username: string; + username: string; - password: string; + password: string; - database: string; + database: string; - schema?: string | null; + schema?: string | null; - sid?: string | null; + sid?: string | null; - ssh: boolean; + ssh: boolean; - privateSSHKey?: string | null; + privateSSHKey?: string | null; - sshHost: string | null; + sshHost: string | null; - sshPort: number | null; + sshPort: number | null; - sshUsername: string | null; + sshUsername: string | null; - ssl: boolean | null; + ssl: boolean | null; - cert: string | null; + cert: string | null; - azure_encryption: boolean | null; + azure_encryption: boolean | null; - signing_key: string; + signing_key: string; - authSource: string | null; + authSource: string | null; - dataCenter?: string | null; + dataCenter?: string | null; - isTestConnection: boolean; + isTestConnection: boolean; } export class ConnectionAgentParams { - id: string; - title?: string | null; - signing_key: string; - token: string; - type: string; - isTestConnection: boolean; + id: string; + title?: string | null; + signing_key: string; + token: string; + type: string; + isTestConnection: boolean; } diff --git a/shared-code/src/data-access-layer/shared/data-structures/custom-field.ds.ts b/shared-code/src/data-access-layer/shared/data-structures/custom-field.ds.ts index 42991e931..e90d59939 100644 --- a/shared-code/src/data-access-layer/shared/data-structures/custom-field.ds.ts +++ b/shared-code/src/data-access-layer/shared/data-structures/custom-field.ds.ts @@ -1,5 +1,5 @@ export class CustomFieldDS { - type: string; - template_string: string; - text: string; + type: string; + template_string: string; + text: string; } diff --git a/shared-code/src/data-access-layer/shared/data-structures/filtering-fields.ds.ts b/shared-code/src/data-access-layer/shared/data-structures/filtering-fields.ds.ts index e9faf9e5c..3b7d4ac00 100644 --- a/shared-code/src/data-access-layer/shared/data-structures/filtering-fields.ds.ts +++ b/shared-code/src/data-access-layer/shared/data-structures/filtering-fields.ds.ts @@ -1,7 +1,7 @@ import { FilterCriteriaEnum } from '../../../shared/enums/filter-criteria.enum.js'; export class FilteringFieldsDS { - field: string; - criteria: FilterCriteriaEnum; - value: unknown; + field: string; + criteria: FilterCriteriaEnum; + value: unknown; } diff --git a/shared-code/src/data-access-layer/shared/data-structures/foreign-key-with-autocomplete-columns.ds.ts b/shared-code/src/data-access-layer/shared/data-structures/foreign-key-with-autocomplete-columns.ds.ts index bb4f4afdb..f91579fbd 100644 --- a/shared-code/src/data-access-layer/shared/data-structures/foreign-key-with-autocomplete-columns.ds.ts +++ b/shared-code/src/data-access-layer/shared/data-structures/foreign-key-with-autocomplete-columns.ds.ts @@ -1,5 +1,5 @@ import { ForeignKeyDS } from './foreign-key.ds.js'; export class ForeignKeyWithAutocompleteColumnsDS extends ForeignKeyDS { - autocomplete_columns: Array; + autocomplete_columns: Array; } diff --git a/shared-code/src/data-access-layer/shared/data-structures/foreign-key.ds.ts b/shared-code/src/data-access-layer/shared/data-structures/foreign-key.ds.ts index de6308b75..66585b1a7 100644 --- a/shared-code/src/data-access-layer/shared/data-structures/foreign-key.ds.ts +++ b/shared-code/src/data-access-layer/shared/data-structures/foreign-key.ds.ts @@ -1,6 +1,6 @@ export class ForeignKeyDS { - referenced_column_name: string; - referenced_table_name: string; - constraint_name: string; - column_name: string; -} \ No newline at end of file + referenced_column_name: string; + referenced_table_name: string; + constraint_name: string; + column_name: string; +} diff --git a/shared-code/src/data-access-layer/shared/data-structures/found-rows.ds.ts b/shared-code/src/data-access-layer/shared/data-structures/found-rows.ds.ts index adadc166a..523ee7555 100644 --- a/shared-code/src/data-access-layer/shared/data-structures/found-rows.ds.ts +++ b/shared-code/src/data-access-layer/shared/data-structures/found-rows.ds.ts @@ -1,7 +1,7 @@ import { RowsPaginationDS } from './rows-pagination.ds.js'; export class FoundRowsDS { - data: Array>; - pagination: RowsPaginationDS; - large_dataset: boolean; + data: Array>; + pagination: RowsPaginationDS; + large_dataset: boolean; } diff --git a/shared-code/src/data-access-layer/shared/data-structures/primary-key.ds.ts b/shared-code/src/data-access-layer/shared/data-structures/primary-key.ds.ts index 357695c11..2b7e600af 100644 --- a/shared-code/src/data-access-layer/shared/data-structures/primary-key.ds.ts +++ b/shared-code/src/data-access-layer/shared/data-structures/primary-key.ds.ts @@ -1,4 +1,4 @@ export class PrimaryKeyDS { - column_name: string; - data_type: string; -} \ No newline at end of file + column_name: string; + data_type: string; +} diff --git a/shared-code/src/data-access-layer/shared/data-structures/referenced-table-names-columns.ds.ts b/shared-code/src/data-access-layer/shared/data-structures/referenced-table-names-columns.ds.ts index 1388f7112..267365add 100644 --- a/shared-code/src/data-access-layer/shared/data-structures/referenced-table-names-columns.ds.ts +++ b/shared-code/src/data-access-layer/shared/data-structures/referenced-table-names-columns.ds.ts @@ -1,4 +1,4 @@ export class ReferencedTableNamesAndColumnsDS { - referenced_by: Array<{ table_name: string; column_name: string }>; - referenced_on_column_name: string; + referenced_by: Array<{ table_name: string; column_name: string }>; + referenced_on_column_name: string; } diff --git a/shared-code/src/data-access-layer/shared/data-structures/rows-pagination.ds.ts b/shared-code/src/data-access-layer/shared/data-structures/rows-pagination.ds.ts index d6064a67a..085b5909a 100644 --- a/shared-code/src/data-access-layer/shared/data-structures/rows-pagination.ds.ts +++ b/shared-code/src/data-access-layer/shared/data-structures/rows-pagination.ds.ts @@ -1,6 +1,6 @@ export class RowsPaginationDS { - total: number; - lastPage: number; - perPage: number; - currentPage: number; + total: number; + lastPage: number; + perPage: number; + currentPage: number; } diff --git a/shared-code/src/data-access-layer/shared/data-structures/table-settings.ds.ts b/shared-code/src/data-access-layer/shared/data-structures/table-settings.ds.ts index 6fab07d7c..96d994e5a 100644 --- a/shared-code/src/data-access-layer/shared/data-structures/table-settings.ds.ts +++ b/shared-code/src/data-access-layer/shared/data-structures/table-settings.ds.ts @@ -1,22 +1,22 @@ import { QueryOrderingEnum } from '../../../shared/enums/query-ordering.enum.js'; export class TableSettingsDS { - table_name: string; - display_name: string; - search_fields: Array; - excluded_fields: Array; - list_fields: Array; - identification_fields: Array; - list_per_page: number; - ordering: QueryOrderingEnum; - ordering_field: string; - identity_column: string; - readonly_fields: Array; - sortable_by: Array; - autocomplete_columns: Array; - columns_view: Array; - can_delete: boolean; - can_update: boolean; - can_add: boolean; - sensitive_fields: Array; + table_name: string; + display_name: string; + search_fields: Array; + excluded_fields: Array; + list_fields: Array; + identification_fields: Array; + list_per_page: number; + ordering: QueryOrderingEnum; + ordering_field: string; + identity_column: string; + readonly_fields: Array; + sortable_by: Array; + autocomplete_columns: Array; + columns_view: Array; + can_delete: boolean; + can_update: boolean; + can_add: boolean; + sensitive_fields: Array; } diff --git a/shared-code/src/data-access-layer/shared/data-structures/table-structure.ds.ts b/shared-code/src/data-access-layer/shared/data-structures/table-structure.ds.ts index f6bd0fe0b..5a98200e5 100644 --- a/shared-code/src/data-access-layer/shared/data-structures/table-structure.ds.ts +++ b/shared-code/src/data-access-layer/shared/data-structures/table-structure.ds.ts @@ -1,13 +1,13 @@ export type DynamoDBType = 'S' | 'N' | 'B' | 'HASH' | 'BOOL' | 'L' | 'M' | 'SS' | 'NS' | 'BS' | 'NULL'; export class TableStructureDS { - allow_null: boolean; - character_maximum_length: number | null; - column_default: string | null; - column_name: string; - data_type: string; - data_type_params: string; - udt_name: string; - extra?: string; - dynamo_db_type?: DynamoDBType; + allow_null: boolean; + character_maximum_length: number | null; + column_default: string | null; + column_name: string; + data_type: string; + data_type_params: string; + udt_name: string; + extra?: string; + dynamo_db_type?: DynamoDBType; } diff --git a/shared-code/src/data-access-layer/shared/data-structures/table-widget.ds.ts b/shared-code/src/data-access-layer/shared/data-structures/table-widget.ds.ts index b082f61a1..15b854812 100644 --- a/shared-code/src/data-access-layer/shared/data-structures/table-widget.ds.ts +++ b/shared-code/src/data-access-layer/shared/data-structures/table-widget.ds.ts @@ -1,11 +1,11 @@ import { TableWidgetTypeEnum } from '../../../shared/enums/table-widget-type.enum.js'; export class TableWidgetDS { - id: string; - field_name: string; - widget_type?: TableWidgetTypeEnum | null; - widget_params: string | null; - widget_options: string | null; - name?: string | null; - description?: string | null; + id: string; + field_name: string; + widget_type?: TableWidgetTypeEnum | null; + widget_params: string | null; + widget_options: string | null; + name?: string | null; + description?: string | null; } diff --git a/shared-code/src/data-access-layer/shared/data-structures/table.ds.ts b/shared-code/src/data-access-layer/shared/data-structures/table.ds.ts index fc6dbab61..100fbc6a9 100644 --- a/shared-code/src/data-access-layer/shared/data-structures/table.ds.ts +++ b/shared-code/src/data-access-layer/shared/data-structures/table.ds.ts @@ -1,4 +1,4 @@ export class TableDS { - tableName: string; - isView: boolean; -} \ No newline at end of file + tableName: string; + isView: boolean; +} diff --git a/shared-code/src/data-access-layer/shared/data-structures/test-result-connection.ds.ts b/shared-code/src/data-access-layer/shared/data-structures/test-result-connection.ds.ts index ef4bb26f8..72e074919 100644 --- a/shared-code/src/data-access-layer/shared/data-structures/test-result-connection.ds.ts +++ b/shared-code/src/data-access-layer/shared/data-structures/test-result-connection.ds.ts @@ -1,4 +1,4 @@ export class TestConnectionResultDS { - result: boolean; - message: string; -} \ No newline at end of file + result: boolean; + message: string; +} diff --git a/shared-code/src/data-access-layer/shared/data-structures/validate-table-settings.ds.ts b/shared-code/src/data-access-layer/shared/data-structures/validate-table-settings.ds.ts index 9742cd5ba..ebda1ce6c 100644 --- a/shared-code/src/data-access-layer/shared/data-structures/validate-table-settings.ds.ts +++ b/shared-code/src/data-access-layer/shared/data-structures/validate-table-settings.ds.ts @@ -3,21 +3,21 @@ import { CustomFieldDS } from './custom-field.ds.js'; import { TableWidgetDS } from './table-widget.ds.js'; export class ValidateTableSettingsDS { - table_name: string; - display_name: string; - search_fields: Array; - excluded_fields: Array; - list_fields: Array; - identification_fields: Array; - list_per_page: number; - ordering: QueryOrderingEnum; - ordering_field: string; - identity_column: string; - readonly_fields: Array; - sortable_by: Array; - autocomplete_columns: Array; - custom_fields?: Array; - table_widgets?: Array; - columns_view?: Array; - icon?: string; + table_name: string; + display_name: string; + search_fields: Array; + excluded_fields: Array; + list_fields: Array; + identification_fields: Array; + list_per_page: number; + ordering: QueryOrderingEnum; + ordering_field: string; + identity_column: string; + readonly_fields: Array; + sortable_by: Array; + autocomplete_columns: Array; + custom_fields?: Array; + table_widgets?: Array; + columns_view?: Array; + icon?: string; } diff --git a/shared-code/src/helpers/binary-hex-string-convertion.ts b/shared-code/src/helpers/binary-hex-string-convertion.ts index b61523392..46243f770 100644 --- a/shared-code/src/helpers/binary-hex-string-convertion.ts +++ b/shared-code/src/helpers/binary-hex-string-convertion.ts @@ -1,25 +1,25 @@ export function binaryToHex( - binaryData: string | Uint8Array | { [key: string]: number } | { type: string; data: number[] }, + binaryData: string | Uint8Array | { [key: string]: number } | { type: string; data: number[] }, ): string { - let buffer: Buffer; - if (binaryData instanceof Uint8Array) { - buffer = Buffer.from(binaryData); - } else if (typeof binaryData === 'object') { - const data = - binaryData.type === 'Buffer' && Array.isArray(binaryData.data) ? binaryData.data : Object.values(binaryData); - buffer = Buffer.from(data); - } else { - buffer = Buffer.from(binaryData, 'binary'); - } - return buffer.toString('hex'); + let buffer: Buffer; + if (binaryData instanceof Uint8Array) { + buffer = Buffer.from(binaryData); + } else if (typeof binaryData === 'object') { + const data = + binaryData.type === 'Buffer' && Array.isArray(binaryData.data) ? binaryData.data : Object.values(binaryData); + buffer = Buffer.from(data); + } else { + buffer = Buffer.from(binaryData, 'binary'); + } + return buffer.toString('hex'); } export function hexToBinary(hexSource: string): Buffer { - return Buffer.from(hexSource, 'hex'); + return Buffer.from(hexSource, 'hex'); } export function isBinary(type: string): boolean { - return ['binary', 'bytea', 'varbinary', 'varbinary(max)', 'tinyblob', 'blob', 'mediumblob', 'longblob'].includes( - type.toLowerCase(), - ); + return ['binary', 'bytea', 'varbinary', 'varbinary(max)', 'tinyblob', 'blob', 'mediumblob', 'longblob'].includes( + type.toLowerCase(), + ); } diff --git a/shared-code/src/helpers/change-object-property-by-name.ts b/shared-code/src/helpers/change-object-property-by-name.ts index 53259d5fa..ba5b50d08 100644 --- a/shared-code/src/helpers/change-object-property-by-name.ts +++ b/shared-code/src/helpers/change-object-property-by-name.ts @@ -1,13 +1,13 @@ export function changeObjPropValByName, TVal>( - obj: TObj, - propName: keyof TObj, - value: TVal, + obj: TObj, + propName: keyof TObj, + value: TVal, ): TObj { - if (propName in obj) { - return { - ...obj, - [propName]: value, - }; - } - return obj; + if (propName in obj) { + return { + ...obj, + [propName]: value, + }; + } + return obj; } diff --git a/shared-code/src/helpers/check-field-autoincrement.ts b/shared-code/src/helpers/check-field-autoincrement.ts index a46db9d32..4760e18e8 100644 --- a/shared-code/src/helpers/check-field-autoincrement.ts +++ b/shared-code/src/helpers/check-field-autoincrement.ts @@ -1,15 +1,15 @@ export function checkFieldAutoincrement(defaultValue: string, extra: string = ''): boolean { - let result = false; - if ( - (defaultValue?.toLowerCase().includes('nextval')) || - (defaultValue?.toLowerCase().includes('generate')) || - (defaultValue?.toLowerCase().includes('autoincrement')) || - (defaultValue?.toLowerCase().includes('auto_increment')) || - (defaultValue?.toLowerCase().includes('sys_guid()')) || - (extra?.toLowerCase().includes('auto_increment')) || - (extra?.toLowerCase().includes('autoincrement')) - ) { - result = true; - } - return result; + let result = false; + if ( + defaultValue?.toLowerCase().includes('nextval') || + defaultValue?.toLowerCase().includes('generate') || + defaultValue?.toLowerCase().includes('autoincrement') || + defaultValue?.toLowerCase().includes('auto_increment') || + defaultValue?.toLowerCase().includes('sys_guid()') || + extra?.toLowerCase().includes('auto_increment') || + extra?.toLowerCase().includes('autoincrement') + ) { + result = true; + } + return result; } diff --git a/shared-code/src/helpers/compate-primitive-array-elements.ts b/shared-code/src/helpers/compate-primitive-array-elements.ts index bbfa85a60..4a02245ac 100644 --- a/shared-code/src/helpers/compate-primitive-array-elements.ts +++ b/shared-code/src/helpers/compate-primitive-array-elements.ts @@ -1,6 +1,6 @@ export function comparePrimitiveArrayElements(arr1: T[] | undefined | null, arr2: T[] | undefined | null): boolean { - if (arr1 == null || arr2 == null) { - return false; - } - return arr1.length === arr2.length && arr1.every(item => arr2.includes(item)); + if (arr1 == null || arr2 == null) { + return false; + } + return arr1.length === arr2.length && arr1.every((item) => arr2.includes(item)); } diff --git a/shared-code/src/helpers/data-access-objects-constants.ts b/shared-code/src/helpers/data-access-objects-constants.ts index 5b667598d..a0725fc91 100644 --- a/shared-code/src/helpers/data-access-objects-constants.ts +++ b/shared-code/src/helpers/data-access-objects-constants.ts @@ -1,6 +1,6 @@ export const DAO_CONSTANTS = { - AUTOCOMPLETE_ROW_LIMIT: 20, - DEFAULT_PAGINATION: { page: 1, perPage: 20 }, - LARGE_DATASET_ROW_LIMIT: 100000, - COUNT_QUERY_TIMEOUT_MS: 2000, -}; \ No newline at end of file + AUTOCOMPLETE_ROW_LIMIT: 20, + DEFAULT_PAGINATION: { page: 1, perPage: 20 }, + LARGE_DATASET_ROW_LIMIT: 100000, + COUNT_QUERY_TIMEOUT_MS: 2000, +}; diff --git a/shared-code/src/helpers/data-structures-builders/table-widget-ds.builder.ts b/shared-code/src/helpers/data-structures-builders/table-widget-ds.builder.ts index 2131da856..88b05322f 100644 --- a/shared-code/src/helpers/data-structures-builders/table-widget-ds.builder.ts +++ b/shared-code/src/helpers/data-structures-builders/table-widget-ds.builder.ts @@ -2,13 +2,13 @@ import { TableWidgetDS } from '../../data-access-layer/shared/data-structures/ta import { IUnknownDataStructure } from '../../shared/interfaces/unknown-datastructure.interface.js'; export function buildTableWidgetDs(tableWidgetParams: IUnknownDataStructure): TableWidgetDS { - return { - id: tableWidgetParams.id, - field_name: tableWidgetParams.field_name, - widget_type: tableWidgetParams.widget_type, - widget_params: tableWidgetParams.widget_params, - widget_options: tableWidgetParams.widget_options, - name: tableWidgetParams.name, - description: tableWidgetParams.description, - }; + return { + id: tableWidgetParams.id, + field_name: tableWidgetParams.field_name, + widget_type: tableWidgetParams.widget_type, + widget_params: tableWidgetParams.widget_params, + widget_options: tableWidgetParams.widget_options, + name: tableWidgetParams.name, + description: tableWidgetParams.description, + }; } diff --git a/shared-code/src/helpers/data-structures-builders/validate-table-settings-ds.builder.ts b/shared-code/src/helpers/data-structures-builders/validate-table-settings-ds.builder.ts index 3ecf6e723..4a981a225 100644 --- a/shared-code/src/helpers/data-structures-builders/validate-table-settings-ds.builder.ts +++ b/shared-code/src/helpers/data-structures-builders/validate-table-settings-ds.builder.ts @@ -3,25 +3,25 @@ import { IUnknownDataStructure } from '../../shared/interfaces/unknown-datastruc import { buildTableWidgetDs } from './table-widget-ds.builder.js'; export function buildValidateTableSettingsDS(tableSettings: IUnknownDataStructure): ValidateTableSettingsDS { - return { - table_name: tableSettings.table_name, - display_name: tableSettings.display_name, - search_fields: tableSettings.search_fields, - excluded_fields: tableSettings.excluded_fields, - list_fields: tableSettings.list_fields, - identification_fields: tableSettings.identification_fields, - list_per_page: tableSettings.list_per_page, - ordering: tableSettings.ordering, - ordering_field: tableSettings.ordering_field, - identity_column: tableSettings.identity_column, - readonly_fields: tableSettings.readonly_fields, - sortable_by: tableSettings.sortable_by, - autocomplete_columns: tableSettings.autocomplete_columns, - custom_fields: tableSettings.custom_fields, - table_widgets: tableSettings.table_widgets - ? tableSettings.table_widgets.map((widget: IUnknownDataStructure) => buildTableWidgetDs(widget)) - : null, - columns_view: tableSettings.columns_view, - icon: tableSettings.icon, - }; + return { + table_name: tableSettings.table_name, + display_name: tableSettings.display_name, + search_fields: tableSettings.search_fields, + excluded_fields: tableSettings.excluded_fields, + list_fields: tableSettings.list_fields, + identification_fields: tableSettings.identification_fields, + list_per_page: tableSettings.list_per_page, + ordering: tableSettings.ordering, + ordering_field: tableSettings.ordering_field, + identity_column: tableSettings.identity_column, + readonly_fields: tableSettings.readonly_fields, + sortable_by: tableSettings.sortable_by, + autocomplete_columns: tableSettings.autocomplete_columns, + custom_fields: tableSettings.custom_fields, + table_widgets: tableSettings.table_widgets + ? tableSettings.table_widgets.map((widget: IUnknownDataStructure) => buildTableWidgetDs(widget)) + : null, + columns_view: tableSettings.columns_view, + icon: tableSettings.icon, + }; } diff --git a/shared-code/src/helpers/enum-to-string.ts b/shared-code/src/helpers/enum-to-string.ts index 81170ecc4..019119e0d 100644 --- a/shared-code/src/helpers/enum-to-string.ts +++ b/shared-code/src/helpers/enum-to-string.ts @@ -1,5 +1,5 @@ export function enumToString(en: any): string { - const values = Object.values(en).filter((v) => typeof v === 'string' || typeof v === 'number'); + const values = Object.values(en).filter((v) => typeof v === 'string' || typeof v === 'number'); - return values.map((v) => (typeof v === 'string' ? `'${v}'` : v)).join(', '); + return values.map((v) => (typeof v === 'string' ? `'${v}'` : v)).join(', '); } diff --git a/shared-code/src/helpers/errors/error-messages.ts b/shared-code/src/helpers/errors/error-messages.ts index fcb3f26d6..9bbcde337 100644 --- a/shared-code/src/helpers/errors/error-messages.ts +++ b/shared-code/src/helpers/errors/error-messages.ts @@ -1,14 +1,14 @@ export const ERROR_MESSAGES = { - DATA_IS_TO_LARGE: `Data is too large`, - TABLE_NOT_FOUND: (tableName: string): string => `Table ${tableName} not found`, - TABLE_SCHEMA_NOT_FOUND: (tableName: string): string => - `Table schema for table ${tableName} not found or this table does not exists`, - CANT_CONNECT_AUTOADMIN_WS: `Connection to autoadmin websocket server failed.`, - PROPERTY_TYPE_REQUIRED: `Property "type" is required`, - CONNECTION_PARAMS_SHOULD_BE_DEFINED: `Connection parameters should be defined`, - CONNECTION_TYPE_INVALID: `Connection type is invalid`, - AGENT_SHOULD_BE_DEFINED: `Agent and agent token should be defined`, - NO_DATA_RETURNED_FROM_AGENT: `No data returned from agent`, - INVALID_OBJECT_ID_FORMAT: `Invalid object id format`, - CLIENT_NOT_CONNECTED: `Client is not connected`, + DATA_IS_TO_LARGE: `Data is too large`, + TABLE_NOT_FOUND: (tableName: string): string => `Table ${tableName} not found`, + TABLE_SCHEMA_NOT_FOUND: (tableName: string): string => + `Table schema for table ${tableName} not found or this table does not exists`, + CANT_CONNECT_AUTOADMIN_WS: `Connection to autoadmin websocket server failed.`, + PROPERTY_TYPE_REQUIRED: `Property "type" is required`, + CONNECTION_PARAMS_SHOULD_BE_DEFINED: `Connection parameters should be defined`, + CONNECTION_TYPE_INVALID: `Connection type is invalid`, + AGENT_SHOULD_BE_DEFINED: `Agent and agent token should be defined`, + NO_DATA_RETURNED_FROM_AGENT: `No data returned from agent`, + INVALID_OBJECT_ID_FORMAT: `Invalid object id format`, + CLIENT_NOT_CONNECTED: `Client is not connected`, }; diff --git a/shared-code/src/helpers/get-numbers-from-string.ts b/shared-code/src/helpers/get-numbers-from-string.ts index 51dfe7b7e..1a8c8aa1f 100644 --- a/shared-code/src/helpers/get-numbers-from-string.ts +++ b/shared-code/src/helpers/get-numbers-from-string.ts @@ -1,3 +1,3 @@ export function getNumbersFromString(str: string): number { - return parseInt(str.match(/\d/g)?.join(''), 10); + return parseInt(str.match(/\d/g)?.join(''), 10); } diff --git a/shared-code/src/helpers/get-property-value-by-descriptor.ts b/shared-code/src/helpers/get-property-value-by-descriptor.ts index 146bdf70c..acdcbfb7b 100644 --- a/shared-code/src/helpers/get-property-value-by-descriptor.ts +++ b/shared-code/src/helpers/get-property-value-by-descriptor.ts @@ -1,7 +1,7 @@ export function getPropertyValueByDescriptor, K extends keyof T>( - obj: T, - propName: K, + obj: T, + propName: K, ): T[K] | undefined { - const descriptor = Object.getOwnPropertyDescriptor(obj, propName); - return descriptor?.value; + const descriptor = Object.getOwnPropertyDescriptor(obj, propName); + return descriptor?.value; } diff --git a/shared-code/src/helpers/get-property-value.ts b/shared-code/src/helpers/get-property-value.ts index 49eb0497d..59bf9623c 100644 --- a/shared-code/src/helpers/get-property-value.ts +++ b/shared-code/src/helpers/get-property-value.ts @@ -1,7 +1,7 @@ export function getPropertyValue(obj: T, propName: K): T[K] | undefined { - const descriptor = Object.getOwnPropertyDescriptor(obj, propName); - if (descriptor) { - return descriptor.value; - } - return undefined; + const descriptor = Object.getOwnPropertyDescriptor(obj, propName); + if (descriptor) { + return descriptor.value; + } + return undefined; } diff --git a/shared-code/src/helpers/get-ssh-tunnel.ts b/shared-code/src/helpers/get-ssh-tunnel.ts index 8837d2018..0e09537d8 100644 --- a/shared-code/src/helpers/get-ssh-tunnel.ts +++ b/shared-code/src/helpers/get-ssh-tunnel.ts @@ -2,29 +2,29 @@ import { createTunnel } from 'tunnel-ssh'; import { ConnectionParams } from '../data-access-layer/shared/data-structures/connections-params.ds.js'; export async function getTunnel(connection: ConnectionParams, freePort: number) { - const { host, port, privateSSHKey, sshPort, sshHost, sshUsername } = connection; - const sshOptions = { - host: sshHost, - port: sshPort, - username: sshUsername, - privateKey: privateSSHKey, - }; + const { host, port, privateSSHKey, sshPort, sshHost, sshUsername } = connection; + const sshOptions = { + host: sshHost, + port: sshPort, + username: sshUsername, + privateKey: privateSSHKey, + }; - const forwardOptions = { - srcAddr: 'localhost', - srcPort: freePort, - dstAddr: host, - dstPort: port, - }; + const forwardOptions = { + srcAddr: 'localhost', + srcPort: freePort, + dstAddr: host, + dstPort: port, + }; - const tunnelOptions = { - autoClose: true, - reconnectOnError: false, - }; + const tunnelOptions = { + autoClose: true, + reconnectOnError: false, + }; - const serverOptions = { - port: freePort, - }; + const serverOptions = { + port: freePort, + }; - return await createTunnel(tunnelOptions, serverOptions, sshOptions, forwardOptions); + return await createTunnel(tunnelOptions, serverOptions, sshOptions, forwardOptions); } diff --git a/shared-code/src/helpers/is-database-date.ts b/shared-code/src/helpers/is-database-date.ts index c95714031..32eaa4a2c 100644 --- a/shared-code/src/helpers/is-database-date.ts +++ b/shared-code/src/helpers/is-database-date.ts @@ -1,67 +1,67 @@ export function isMSSQLDateOrTimeType(dataType: string): boolean { - return ['date', 'datetime', 'datetime2', 'datetimeoffset', 'smalldatetime', 'time'].includes(dataType); + return ['date', 'datetime', 'datetime2', 'datetimeoffset', 'smalldatetime', 'time'].includes(dataType); } export function isMSSQLDateStringByRegexp(value: string): boolean { - return /(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2}.\d{3}Z)/.test(value); + return /(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2}.\d{3}Z)/.test(value); } export function isMySqlDateOrTimeType(dataType: string): boolean { - return ['date', 'time', 'datetime', 'timestamp'].includes(dataType.toLowerCase()); + return ['date', 'time', 'datetime', 'timestamp'].includes(dataType.toLowerCase()); } export function isMySQLDateStringByRegexp(value: string): boolean { - return /^\d{4}-\d{2}-\d{2}$/.test(value); + return /^\d{4}-\d{2}-\d{2}$/.test(value); } export function isOracleDateOrTimeType(type: string): boolean { - if (type.toLowerCase().includes('timestamp')) { - return true; - } - const dateTypes = [ - 'date', - 'timestamp', - 'timestamp with time zone', - 'timestamp with local time zone', - 'timestamp(6) with local time zone', - 'timestamp(0) with local time zone', - ]; - return dateTypes.includes(type.toLowerCase()); + if (type.toLowerCase().includes('timestamp')) { + return true; + } + const dateTypes = [ + 'date', + 'timestamp', + 'timestamp with time zone', + 'timestamp with local time zone', + 'timestamp(6) with local time zone', + 'timestamp(0) with local time zone', + ]; + return dateTypes.includes(type.toLowerCase()); } export function isOracleTimeType(type: string): boolean { - return [ - 'timestamp', - 'timestamp with time zone', - 'timestamp with local time zone', - 'timestamp(6) with local time zone', - 'timestamp(0) with local time zone', - ].includes(type.toLowerCase()); + return [ + 'timestamp', + 'timestamp with time zone', + 'timestamp with local time zone', + 'timestamp(6) with local time zone', + 'timestamp(0) with local time zone', + ].includes(type.toLowerCase()); } export function isOracleDateType(type: string): boolean { - return ['date'].includes(type.toLowerCase()); + return ['date'].includes(type.toLowerCase()); } export function isOracleDateStringByRegexp(value: string): boolean { - const dateRegexp = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/; - return dateRegexp.test(value); + const dateRegexp = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/; + return dateRegexp.test(value); } export function isPostgresDateOrTimeType(dataType: string): boolean { - return ['date', 'time', 'timestamp', 'timestamptz', 'timestamp with time zone'].includes(dataType); + return ['date', 'time', 'timestamp', 'timestamptz', 'timestamp with time zone'].includes(dataType); } export function isPostgresDateStringByRegexp(value: string): boolean { - const dateRegexp = /^(\d{4})-(\d{2})-(\d{2})$/; - return dateRegexp.test(value); + const dateRegexp = /^(\d{4})-(\d{2})-(\d{2})$/; + return dateRegexp.test(value); } export function formatOracleDate(date: Date) { - const monthNames = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC']; - const day = date.getDate(); - const monthIndex = date.getMonth(); - const year = date.getFullYear().toString().slice(-2); - // eslint-disable-next-line security/detect-object-injection - const resultString = `${day}-${monthNames[monthIndex]}-${year}`; - return resultString; + const monthNames = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC']; + const day = date.getDate(); + const monthIndex = date.getMonth(); + const year = date.getFullYear().toString().slice(-2); + // eslint-disable-next-line security/detect-object-injection + const resultString = `${day}-${monthNames[monthIndex]}-${year}`; + return resultString; } diff --git a/shared-code/src/helpers/is-object-empty.ts b/shared-code/src/helpers/is-object-empty.ts index c5741020a..49d85f523 100644 --- a/shared-code/src/helpers/is-object-empty.ts +++ b/shared-code/src/helpers/is-object-empty.ts @@ -1,6 +1,6 @@ export function isObjectEmpty(obj: any): boolean { - if (typeof obj !== 'object' || Array.isArray(obj)) { - throw new Error('Input is not an object'); - } - return Object.keys(obj).length === 0; + if (typeof obj !== 'object' || Array.isArray(obj)) { + throw new Error('Input is not an object'); + } + return Object.keys(obj).length === 0; } diff --git a/shared-code/src/helpers/object-kyes-to-lowercase.ts b/shared-code/src/helpers/object-kyes-to-lowercase.ts index 9d318b0c0..c3e893729 100644 --- a/shared-code/src/helpers/object-kyes-to-lowercase.ts +++ b/shared-code/src/helpers/object-kyes-to-lowercase.ts @@ -1,13 +1,13 @@ export function objectKeysToLowercase(obj: Record): Record { - const result: Record = {}; + const result: Record = {}; - for (const [key, value] of Object.entries(obj)) { - if (typeof value === 'object' && value !== null) { - result[key.toLowerCase()] = objectKeysToLowercase(value); - } else { - result[key.toLowerCase()] = value; - } - } + for (const [key, value] of Object.entries(obj)) { + if (typeof value === 'object' && value !== null) { + result[key.toLowerCase()] = objectKeysToLowercase(value); + } else { + result[key.toLowerCase()] = value; + } + } - return result; + return result; } diff --git a/shared-code/src/helpers/rename-object-keyname.ts b/shared-code/src/helpers/rename-object-keyname.ts index da81012f6..a7686e62c 100644 --- a/shared-code/src/helpers/rename-object-keyname.ts +++ b/shared-code/src/helpers/rename-object-keyname.ts @@ -1,12 +1,12 @@ /* eslint-disable security/detect-object-injection */ interface RenamableObject { - [key: string]: any; + [key: string]: any; } export function renameObjectKeyName(obj: RenamableObject, oldKey: string, newKey: string): void { - if (oldKey === newKey || !Object.hasOwn(obj, oldKey)) { - return; - } - obj[newKey] = obj[oldKey]; - delete obj[oldKey]; + if (oldKey === newKey || !Object.hasOwn(obj, oldKey)) { + return; + } + obj[newKey] = obj[oldKey]; + delete obj[oldKey]; } diff --git a/shared-code/src/helpers/set-property-value.ts b/shared-code/src/helpers/set-property-value.ts index ca5abc1c1..19ddd8325 100644 --- a/shared-code/src/helpers/set-property-value.ts +++ b/shared-code/src/helpers/set-property-value.ts @@ -1,5 +1,5 @@ export function setPropertyValue(obj: TObj, propName: keyof TObj, value: TObj[keyof TObj]): void { - if (Object.hasOwn(obj, propName)) { - obj[propName] = value; - } + if (Object.hasOwn(obj, propName)) { + obj[propName] = value; + } } diff --git a/shared-code/src/helpers/validation/table-settings-validation-errors.ts b/shared-code/src/helpers/validation/table-settings-validation-errors.ts index b2eb561d7..14225fedc 100644 --- a/shared-code/src/helpers/validation/table-settings-validation-errors.ts +++ b/shared-code/src/helpers/validation/table-settings-validation-errors.ts @@ -2,19 +2,19 @@ import { QueryOrderingEnum } from '../../shared/enums/query-ordering.enum.js'; import { enumToString } from '../../helpers/enum-to-string.js'; export const TABLE_SETTINGS_VALIDATION_ERRORS = { - MUST_BE_ARRAY: (fieldName: string) => `The field "${fieldName}" must be an array`, - NO_SUCH_FIELDS_IN_TABLES: (fields: Array, tableName: string) => - `There are no such fields: ${fields.join(', ')} - in the table "${tableName}"`, - ORDERING_FIELD_INCORRECT: `Value of sorting order is incorrect. You can choose from values ${enumToString( - QueryOrderingEnum, - )}`, - LIST_PER_PAGE_INCORRECT: `You can't display less than one row per page`, - CANT_LIST_AND_EXCLUDE: (fieldName: string) => - `You cannot select the same field ${fieldName ? fieldName : 'names'} to list and exclude`, - CANT_ORDER_AND_EXCLUDE: `You cannot select the same field names to order and exclude`, - CANT_READONLY_AND_EXCLUDE: (fieldName: string) => - `You cannot select the same field ${fieldName ? fieldName : 'names'} to be readonly and exclude`, - CANT_EXCLUDE_PRIMARY_KEY: (key: string) => `You cannot exclude primary key ${key}`, - CANT_VIEW_AND_EXCLUDE: (fieldName: string) => - `You cannot select the same field ${fieldName ? fieldName : 'names'} to view and exclude`, + MUST_BE_ARRAY: (fieldName: string) => `The field "${fieldName}" must be an array`, + NO_SUCH_FIELDS_IN_TABLES: (fields: Array, tableName: string) => + `There are no such fields: ${fields.join(', ')} - in the table "${tableName}"`, + ORDERING_FIELD_INCORRECT: `Value of sorting order is incorrect. You can choose from values ${enumToString( + QueryOrderingEnum, + )}`, + LIST_PER_PAGE_INCORRECT: `You can't display less than one row per page`, + CANT_LIST_AND_EXCLUDE: (fieldName: string) => + `You cannot select the same field ${fieldName ? fieldName : 'names'} to list and exclude`, + CANT_ORDER_AND_EXCLUDE: `You cannot select the same field names to order and exclude`, + CANT_READONLY_AND_EXCLUDE: (fieldName: string) => + `You cannot select the same field ${fieldName ? fieldName : 'names'} to be readonly and exclude`, + CANT_EXCLUDE_PRIMARY_KEY: (key: string) => `You cannot exclude primary key ${key}`, + CANT_VIEW_AND_EXCLUDE: (fieldName: string) => + `You cannot select the same field ${fieldName ? fieldName : 'names'} to view and exclude`, }; diff --git a/shared-code/src/helpers/validation/table-settings-validator.ts b/shared-code/src/helpers/validation/table-settings-validator.ts index c3424a4be..9a22df158 100644 --- a/shared-code/src/helpers/validation/table-settings-validator.ts +++ b/shared-code/src/helpers/validation/table-settings-validator.ts @@ -6,147 +6,147 @@ import { isObjectEmpty } from '../is-object-empty.js'; import { TABLE_SETTINGS_VALIDATION_ERRORS } from './table-settings-validation-errors.js'; export function tableSettingsFieldValidator( - tableStructure: any, - primaryColumns: Array, - settings: ValidateTableSettingsDS | TableSettingsDS, + tableStructure: any, + primaryColumns: Array, + settings: ValidateTableSettingsDS | TableSettingsDS, ): Array { - const errorMessages = []; - if (isObjectEmpty(settings)) { - return errorMessages; - } - const { - search_fields, - excluded_fields, - list_fields, - readonly_fields, - sortable_by, - ordering_field, - ordering, - list_per_page, - identification_fields, - columns_view, - identity_column, - } = settings; - - const columnNames = tableStructure.map((column) => { - return column.column_name; - }); - //******************************************* - if (search_fields && !Array.isArray(search_fields)) { - errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.MUST_BE_ARRAY(`search_fields`)); - } - - if (excluded_fields && !Array.isArray(excluded_fields)) { - errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.MUST_BE_ARRAY(`excluded_fields`)); - } - - if (list_fields && !Array.isArray(list_fields)) { - errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.MUST_BE_ARRAY(`list_fields`)); - } - - if (identification_fields && !Array.isArray(identification_fields)) { - errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.MUST_BE_ARRAY('identification_fields')); - } - - if (readonly_fields && !Array.isArray(readonly_fields)) { - errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.MUST_BE_ARRAY(`readonly_fields`)); - } - - if (sortable_by && !Array.isArray(sortable_by)) { - errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.MUST_BE_ARRAY(`sortable_by`)); - } - - if (columns_view && !Array.isArray(columns_view)) { - errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.MUST_BE_ARRAY(`columns_view`)); - } - - if (errorMessages.length > 0) { - return errorMessages; - } - - //********************************************* - function excludedFields(checkedFields: Array, existingFields: Array): Array { - const excludedFields = []; - if (!checkedFields) { - return excludedFields; - } - for (const checkedField of checkedFields) { - if (!checkedField) { - continue; - } - if (!existingFields.includes(checkedField)) { - excludedFields.push(checkedField); - } - } - return excludedFields; - } - - const errors = Array.prototype.concat( - excludedFields(search_fields, columnNames), - excludedFields(excluded_fields, columnNames), - excludedFields(list_fields, columnNames), - excludedFields(identification_fields, columnNames), - excludedFields(readonly_fields, columnNames), - excludedFields(sortable_by, columnNames), - excludedFields([ordering_field], columnNames), - excludedFields(columns_view, columnNames), - excludedFields([identity_column], columnNames), - ); - - if (errors.length > 0) { - errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.NO_SUCH_FIELDS_IN_TABLES(errors, settings.table_name)); - } - - if (ordering) { - if (!Object.keys(QueryOrderingEnum).find((key) => key === ordering)) { - errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.ORDERING_FIELD_INCORRECT); - } - } - - if ((list_per_page && list_per_page < 0) || list_per_page === 0) { - errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.LIST_PER_PAGE_INCORRECT); - } - - if (excluded_fields) { - for (const field of search_fields) { - const index = excluded_fields.indexOf(field); - if (index >= 0) { - errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.CANT_LIST_AND_EXCLUDE(field)); - } - } - - const orderingFieldIndex = excluded_fields.indexOf(ordering_field); - if (orderingFieldIndex >= 0) { - errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.CANT_ORDER_AND_EXCLUDE); - } - - if (readonly_fields && readonly_fields.length > 0) { - for (const field of readonly_fields) { - const index = excluded_fields.indexOf(field); - if (index >= 0) { - errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.CANT_READONLY_AND_EXCLUDE(field)); - } - } - } - - if (columns_view && columns_view.length > 0) { - for (const field of columns_view) { - const index = excluded_fields.indexOf(field); - if (index >= 0) { - errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.CANT_VIEW_AND_EXCLUDE(field)); - } - } - } - - if (primaryColumns && primaryColumns.length > 0) { - for (const column of primaryColumns) { - const index = excluded_fields.indexOf(column.column_name); - if (index >= 0) { - errors.push(TABLE_SETTINGS_VALIDATION_ERRORS.CANT_EXCLUDE_PRIMARY_KEY(column.column_name)); - } - } - } - } - - return errorMessages; + const errorMessages = []; + if (isObjectEmpty(settings)) { + return errorMessages; + } + const { + search_fields, + excluded_fields, + list_fields, + readonly_fields, + sortable_by, + ordering_field, + ordering, + list_per_page, + identification_fields, + columns_view, + identity_column, + } = settings; + + const columnNames = tableStructure.map((column) => { + return column.column_name; + }); + //******************************************* + if (search_fields && !Array.isArray(search_fields)) { + errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.MUST_BE_ARRAY(`search_fields`)); + } + + if (excluded_fields && !Array.isArray(excluded_fields)) { + errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.MUST_BE_ARRAY(`excluded_fields`)); + } + + if (list_fields && !Array.isArray(list_fields)) { + errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.MUST_BE_ARRAY(`list_fields`)); + } + + if (identification_fields && !Array.isArray(identification_fields)) { + errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.MUST_BE_ARRAY('identification_fields')); + } + + if (readonly_fields && !Array.isArray(readonly_fields)) { + errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.MUST_BE_ARRAY(`readonly_fields`)); + } + + if (sortable_by && !Array.isArray(sortable_by)) { + errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.MUST_BE_ARRAY(`sortable_by`)); + } + + if (columns_view && !Array.isArray(columns_view)) { + errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.MUST_BE_ARRAY(`columns_view`)); + } + + if (errorMessages.length > 0) { + return errorMessages; + } + + //********************************************* + function excludedFields(checkedFields: Array, existingFields: Array): Array { + const excludedFields = []; + if (!checkedFields) { + return excludedFields; + } + for (const checkedField of checkedFields) { + if (!checkedField) { + continue; + } + if (!existingFields.includes(checkedField)) { + excludedFields.push(checkedField); + } + } + return excludedFields; + } + + const errors = Array.prototype.concat( + excludedFields(search_fields, columnNames), + excludedFields(excluded_fields, columnNames), + excludedFields(list_fields, columnNames), + excludedFields(identification_fields, columnNames), + excludedFields(readonly_fields, columnNames), + excludedFields(sortable_by, columnNames), + excludedFields([ordering_field], columnNames), + excludedFields(columns_view, columnNames), + excludedFields([identity_column], columnNames), + ); + + if (errors.length > 0) { + errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.NO_SUCH_FIELDS_IN_TABLES(errors, settings.table_name)); + } + + if (ordering) { + if (!Object.keys(QueryOrderingEnum).find((key) => key === ordering)) { + errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.ORDERING_FIELD_INCORRECT); + } + } + + if ((list_per_page && list_per_page < 0) || list_per_page === 0) { + errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.LIST_PER_PAGE_INCORRECT); + } + + if (excluded_fields) { + for (const field of search_fields) { + const index = excluded_fields.indexOf(field); + if (index >= 0) { + errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.CANT_LIST_AND_EXCLUDE(field)); + } + } + + const orderingFieldIndex = excluded_fields.indexOf(ordering_field); + if (orderingFieldIndex >= 0) { + errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.CANT_ORDER_AND_EXCLUDE); + } + + if (readonly_fields && readonly_fields.length > 0) { + for (const field of readonly_fields) { + const index = excluded_fields.indexOf(field); + if (index >= 0) { + errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.CANT_READONLY_AND_EXCLUDE(field)); + } + } + } + + if (columns_view && columns_view.length > 0) { + for (const field of columns_view) { + const index = excluded_fields.indexOf(field); + if (index >= 0) { + errorMessages.push(TABLE_SETTINGS_VALIDATION_ERRORS.CANT_VIEW_AND_EXCLUDE(field)); + } + } + } + + if (primaryColumns && primaryColumns.length > 0) { + for (const column of primaryColumns) { + const index = excluded_fields.indexOf(column.column_name); + if (index >= 0) { + errors.push(TABLE_SETTINGS_VALIDATION_ERRORS.CANT_EXCLUDE_PRIMARY_KEY(column.column_name)); + } + } + } + } + + return errorMessages; } diff --git a/shared-code/src/knex-manager/knex-manager.ts b/shared-code/src/knex-manager/knex-manager.ts index c011a8df5..19521d9b8 100644 --- a/shared-code/src/knex-manager/knex-manager.ts +++ b/shared-code/src/knex-manager/knex-manager.ts @@ -4,238 +4,238 @@ import { ConnectionParams } from '../data-access-layer/shared/data-structures/co import { getTunnel } from '../helpers/get-ssh-tunnel.js'; import { LRUStorage } from '../caching/lru-storage.js'; export class KnexManager { - static knexStorage() { - const knexMap = new Map Promise>>(); - - knexMap.set('postgres', async (connection: ConnectionParams): Promise> => { - const cachedKnex = LRUStorage.getCachedKnex(connection); - if (cachedKnex) { - try { - await cachedKnex.raw('SELECT 1'); - return cachedKnex; - } catch (_error) { - LRUStorage.delKnexCache(connection); - } - } - if (connection.ssh) { - const newKnex = await KnexManager.createTunneledKnex(connection); - LRUStorage.setKnexCache(connection, newKnex); - return newKnex; - } - const newKnex = KnexManager.getPostgresKnex(connection); - LRUStorage.setKnexCache(connection, newKnex); - return newKnex; - }); - - knexMap.set('mysql2', async (connection: ConnectionParams): Promise> => { - const cachedKnex = LRUStorage.getCachedKnex(connection); - if (cachedKnex) { - try { - await cachedKnex.raw('SELECT 1'); - return cachedKnex; - } catch (_error) { - LRUStorage.delKnexCache(connection); - } - } - if (connection.ssh) { - const newKnex = await KnexManager.createTunneledKnex(connection); - LRUStorage.setKnexCache(connection, newKnex); - return newKnex; - } - const newKnex = KnexManager.getMysqlKnex(connection); - LRUStorage.setKnexCache(connection, newKnex); - return newKnex; - }); - - knexMap.set('mssql', async (connection: ConnectionParams): Promise> => { - const cachedKnex = LRUStorage.getCachedKnex(connection); - if (cachedKnex) { - return cachedKnex; - } - if (connection.ssh) { - const newKnex = await KnexManager.createTunneledKnex(connection); - LRUStorage.setKnexCache(connection, newKnex); - return newKnex; - } - const newKnex = KnexManager.getMssqlKnex(connection); - LRUStorage.setKnexCache(connection, newKnex); - return newKnex; - }); - - knexMap.set('oracledb', async (connection: ConnectionParams): Promise> => { - const cachedKnex = LRUStorage.getCachedKnex(connection); - if (cachedKnex) { - return cachedKnex; - } - if (connection.ssh) { - const newKnex = await KnexManager.createTunneledKnex(connection); - LRUStorage.setKnexCache(connection, newKnex); - return newKnex; - } - const newKnex = KnexManager.getOracleKnex(connection); - LRUStorage.setKnexCache(connection, newKnex); - return newKnex; - }); - - return knexMap; - } - - private static async createTunneledKnex(connection: ConnectionParams): Promise> { - const connectionCopy = { ...connection }; - return new Promise>(async (resolve, reject): Promise> => { - const cachedTnl = LRUStorage.getTunnelCache(connectionCopy); - if (cachedTnl?.knex && cachedTnl.server && cachedTnl.client) { - resolve(cachedTnl.knex); - return; - } - const freePort = await getPort(); - try { - const [server, client] = await getTunnel(connectionCopy, freePort); - connection.host = '127.0.0.1'; - connection.port = freePort; - const knex = KnexManager.getKnex(connection); - const tnlCachedObj = { - server: server, - client: client, - knex: knex, - }; - - LRUStorage.setTunnelCache(connectionCopy, tnlCachedObj); - - resolve(tnlCachedObj.knex); - - client.on('error', (e) => { - LRUStorage.delTunnelCache(connectionCopy); - reject(e); - return; - }); - - server.on('error', (e) => { - LRUStorage.delTunnelCache(connectionCopy); - reject(e); - return; - }); - return; - } catch (error) { - LRUStorage.delTunnelCache(connectionCopy); - reject(error); - return; - } - }); - } - - private static getPostgresKnex(connection: ConnectionParams): Knex { - const { host, username, password, database, port, type, cert, ssl } = connection; - if (process.env.NODE_ENV === 'test') { - const newKnex = knex({ - client: type, - connection: { - host: host, - user: username, - password: password, - database: database, - port: port, - }, - }); - return newKnex; - } - - if (host === process.env.POSTGRES_CONNECTION_HOST) { - const newKnex = knex({ - client: type, - connection: { - host: host, - user: username, - password: password, - database: database, - port: port, - application_name: 'rocketadmin', - ssl: { - rejectUnauthorized: false, - }, - }, - }); - return newKnex; - } - const newKnex = knex({ - client: type, - connection: { - host: host, - user: username, - password: password, - database: database, - port: port, - application_name: 'rocketadmin', - ssl: ssl ? { ca: cert ?? undefined, rejectUnauthorized: !cert } : false, - }, - }); - return newKnex; - } - - private static getMysqlKnex(connection: ConnectionParams): Knex { - const { host, username, password, database, port, ssl, cert } = connection; - const newKnex = knex({ - client: 'mysql2', - connection: { - host: host, - user: username, - password: password, - database: database, - port: port, - ssl: ssl ? { ca: cert ?? undefined, rejectUnauthorized: !cert } : false, - }, - }); - return newKnex; - } - - private static getMssqlKnex(connection: ConnectionParams): Knex { - const { host, username, password, database, port, type, ssl, cert, azure_encryption } = connection; - const newKnex = knex({ - client: type, - connection: { - host: host, - user: username, - password: password, - database: database, - port: port, - ssl: ssl ? { ca: cert ?? undefined, rejectUnauthorized: !cert } : false, - options: azure_encryption - ? { - encrypt: azure_encryption, - } - : undefined, - }, - }); - return newKnex; - } - - private static getOracleKnex(connection: ConnectionParams): Knex { - const { host, username, password, database, port, type, sid, ssl, cert } = connection; - const newKnex = knex({ - client: type, - connection: { - user: username, - database: database, - password: password, - connectString: `${host}:${port}/${sid ? sid : ''}`, - ssl: ssl ? { ca: cert ?? undefined, rejectUnauthorized: !cert } : false, - }, - }); - return newKnex; - } - - private static getKnex(connection: ConnectionParams): Knex { - const { type } = connection; - switch (type) { - case 'mysql' as any: - case 'mysql2': - return KnexManager.getMysqlKnex(connection); - case 'postgres': - return KnexManager.getPostgresKnex(connection); - case 'oracledb': - return KnexManager.getOracleKnex(connection); - case 'mssql': - return KnexManager.getMssqlKnex(connection); - } - } + static knexStorage() { + const knexMap = new Map Promise>>(); + + knexMap.set('postgres', async (connection: ConnectionParams): Promise> => { + const cachedKnex = LRUStorage.getCachedKnex(connection); + if (cachedKnex) { + try { + await cachedKnex.raw('SELECT 1'); + return cachedKnex; + } catch (_error) { + LRUStorage.delKnexCache(connection); + } + } + if (connection.ssh) { + const newKnex = await KnexManager.createTunneledKnex(connection); + LRUStorage.setKnexCache(connection, newKnex); + return newKnex; + } + const newKnex = KnexManager.getPostgresKnex(connection); + LRUStorage.setKnexCache(connection, newKnex); + return newKnex; + }); + + knexMap.set('mysql2', async (connection: ConnectionParams): Promise> => { + const cachedKnex = LRUStorage.getCachedKnex(connection); + if (cachedKnex) { + try { + await cachedKnex.raw('SELECT 1'); + return cachedKnex; + } catch (_error) { + LRUStorage.delKnexCache(connection); + } + } + if (connection.ssh) { + const newKnex = await KnexManager.createTunneledKnex(connection); + LRUStorage.setKnexCache(connection, newKnex); + return newKnex; + } + const newKnex = KnexManager.getMysqlKnex(connection); + LRUStorage.setKnexCache(connection, newKnex); + return newKnex; + }); + + knexMap.set('mssql', async (connection: ConnectionParams): Promise> => { + const cachedKnex = LRUStorage.getCachedKnex(connection); + if (cachedKnex) { + return cachedKnex; + } + if (connection.ssh) { + const newKnex = await KnexManager.createTunneledKnex(connection); + LRUStorage.setKnexCache(connection, newKnex); + return newKnex; + } + const newKnex = KnexManager.getMssqlKnex(connection); + LRUStorage.setKnexCache(connection, newKnex); + return newKnex; + }); + + knexMap.set('oracledb', async (connection: ConnectionParams): Promise> => { + const cachedKnex = LRUStorage.getCachedKnex(connection); + if (cachedKnex) { + return cachedKnex; + } + if (connection.ssh) { + const newKnex = await KnexManager.createTunneledKnex(connection); + LRUStorage.setKnexCache(connection, newKnex); + return newKnex; + } + const newKnex = KnexManager.getOracleKnex(connection); + LRUStorage.setKnexCache(connection, newKnex); + return newKnex; + }); + + return knexMap; + } + + private static async createTunneledKnex(connection: ConnectionParams): Promise> { + const connectionCopy = { ...connection }; + return new Promise>(async (resolve, reject): Promise> => { + const cachedTnl = LRUStorage.getTunnelCache(connectionCopy); + if (cachedTnl?.knex && cachedTnl.server && cachedTnl.client) { + resolve(cachedTnl.knex); + return; + } + const freePort = await getPort(); + try { + const [server, client] = await getTunnel(connectionCopy, freePort); + connection.host = '127.0.0.1'; + connection.port = freePort; + const knex = KnexManager.getKnex(connection); + const tnlCachedObj = { + server: server, + client: client, + knex: knex, + }; + + LRUStorage.setTunnelCache(connectionCopy, tnlCachedObj); + + resolve(tnlCachedObj.knex); + + client.on('error', (e) => { + LRUStorage.delTunnelCache(connectionCopy); + reject(e); + return; + }); + + server.on('error', (e) => { + LRUStorage.delTunnelCache(connectionCopy); + reject(e); + return; + }); + return; + } catch (error) { + LRUStorage.delTunnelCache(connectionCopy); + reject(error); + return; + } + }); + } + + private static getPostgresKnex(connection: ConnectionParams): Knex { + const { host, username, password, database, port, type, cert, ssl } = connection; + if (process.env.NODE_ENV === 'test') { + const newKnex = knex({ + client: type, + connection: { + host: host, + user: username, + password: password, + database: database, + port: port, + }, + }); + return newKnex; + } + + if (host === process.env.POSTGRES_CONNECTION_HOST) { + const newKnex = knex({ + client: type, + connection: { + host: host, + user: username, + password: password, + database: database, + port: port, + application_name: 'rocketadmin', + ssl: { + rejectUnauthorized: false, + }, + }, + }); + return newKnex; + } + const newKnex = knex({ + client: type, + connection: { + host: host, + user: username, + password: password, + database: database, + port: port, + application_name: 'rocketadmin', + ssl: ssl ? { ca: cert ?? undefined, rejectUnauthorized: !cert } : false, + }, + }); + return newKnex; + } + + private static getMysqlKnex(connection: ConnectionParams): Knex { + const { host, username, password, database, port, ssl, cert } = connection; + const newKnex = knex({ + client: 'mysql2', + connection: { + host: host, + user: username, + password: password, + database: database, + port: port, + ssl: ssl ? { ca: cert ?? undefined, rejectUnauthorized: !cert } : false, + }, + }); + return newKnex; + } + + private static getMssqlKnex(connection: ConnectionParams): Knex { + const { host, username, password, database, port, type, ssl, cert, azure_encryption } = connection; + const newKnex = knex({ + client: type, + connection: { + host: host, + user: username, + password: password, + database: database, + port: port, + ssl: ssl ? { ca: cert ?? undefined, rejectUnauthorized: !cert } : false, + options: azure_encryption + ? { + encrypt: azure_encryption, + } + : undefined, + }, + }); + return newKnex; + } + + private static getOracleKnex(connection: ConnectionParams): Knex { + const { host, username, password, database, port, type, sid, ssl, cert } = connection; + const newKnex = knex({ + client: type, + connection: { + user: username, + database: database, + password: password, + connectString: `${host}:${port}/${sid ? sid : ''}`, + ssl: ssl ? { ca: cert ?? undefined, rejectUnauthorized: !cert } : false, + }, + }); + return newKnex; + } + + private static getKnex(connection: ConnectionParams): Knex { + const { type } = connection; + switch (type) { + case 'mysql' as any: + case 'mysql2': + return KnexManager.getMysqlKnex(connection); + case 'postgres': + return KnexManager.getPostgresKnex(connection); + case 'oracledb': + return KnexManager.getOracleKnex(connection); + case 'mssql': + return KnexManager.getMssqlKnex(connection); + } + } } diff --git a/shared-code/src/shared/enums/connection-types-enum.ts b/shared-code/src/shared/enums/connection-types-enum.ts index adc0f83b6..fc74c8f37 100644 --- a/shared-code/src/shared/enums/connection-types-enum.ts +++ b/shared-code/src/shared/enums/connection-types-enum.ts @@ -1,48 +1,48 @@ export enum ConnectionTypesEnum { - postgres = 'postgres', - mysql = 'mysql', - mysql2 = 'mysql2', - oracledb = 'oracledb', - mssql = 'mssql', - ibmdb2 = 'ibmdb2', - mongodb = 'mongodb', - dynamodb = 'dynamodb', - elasticsearch = 'elasticsearch', - cassandra = 'cassandra', - redis = 'redis', - clickhouse = 'clickhouse', - agent_postgres = 'agent_postgres', - agent_mysql = 'agent_mysql', - agent_oracledb = 'agent_oracledb', - agent_mssql = 'agent_mssql', - agent_ibmdb2 = 'agent_ibmdb2', - agent_mongodb = 'agent_mongodb', - agent_cassandra = 'agent_cassandra', - agent_redis = 'agent_redis', - agent_clickhouse = 'agent_clickhouse', + postgres = 'postgres', + mysql = 'mysql', + mysql2 = 'mysql2', + oracledb = 'oracledb', + mssql = 'mssql', + ibmdb2 = 'ibmdb2', + mongodb = 'mongodb', + dynamodb = 'dynamodb', + elasticsearch = 'elasticsearch', + cassandra = 'cassandra', + redis = 'redis', + clickhouse = 'clickhouse', + agent_postgres = 'agent_postgres', + agent_mysql = 'agent_mysql', + agent_oracledb = 'agent_oracledb', + agent_mssql = 'agent_mssql', + agent_ibmdb2 = 'agent_ibmdb2', + agent_mongodb = 'agent_mongodb', + agent_cassandra = 'agent_cassandra', + agent_redis = 'agent_redis', + agent_clickhouse = 'agent_clickhouse', } export enum ConnectionTypeTestEnum { - postgres = 'postgres', - mysql = 'mysql', - mysql2 = 'mysql2', - oracledb = 'oracledb', - mssql = 'mssql', - ibmdb2 = 'ibmdb2', - mongodb = 'mongodb', - dynamodb = 'dynamodb', - elasticsearch = 'elasticsearch', - cassandra = 'cassandra', - redis = 'redis', - clickhouse = 'clickhouse', - agent_postgres = 'agent_postgres', - agent_mysql = 'agent_mysql', - agent_oracledb = 'agent_oracledb', - agent_mssql = 'agent_mssql', - agent_ibmdb2 = 'agent_ibmdb2', - agent_mongodb = 'agent_mongodb', - agent_elasticsearch = 'agent_elasticsearch', - agent_cassandra = 'agent_cassandra', - agent_redis = 'agent_redis', - agent_clickhouse = 'agent_clickhouse', + postgres = 'postgres', + mysql = 'mysql', + mysql2 = 'mysql2', + oracledb = 'oracledb', + mssql = 'mssql', + ibmdb2 = 'ibmdb2', + mongodb = 'mongodb', + dynamodb = 'dynamodb', + elasticsearch = 'elasticsearch', + cassandra = 'cassandra', + redis = 'redis', + clickhouse = 'clickhouse', + agent_postgres = 'agent_postgres', + agent_mysql = 'agent_mysql', + agent_oracledb = 'agent_oracledb', + agent_mssql = 'agent_mssql', + agent_ibmdb2 = 'agent_ibmdb2', + agent_mongodb = 'agent_mongodb', + agent_elasticsearch = 'agent_elasticsearch', + agent_cassandra = 'agent_cassandra', + agent_redis = 'agent_redis', + agent_clickhouse = 'agent_clickhouse', } diff --git a/shared-code/src/shared/enums/data-access-object-commands.enum.ts b/shared-code/src/shared/enums/data-access-object-commands.enum.ts index 9e4aefeda..2aa747693 100644 --- a/shared-code/src/shared/enums/data-access-object-commands.enum.ts +++ b/shared-code/src/shared/enums/data-access-object-commands.enum.ts @@ -1,21 +1,21 @@ export enum DataAccessObjectCommandsEnum { - addRowInTable = 'addRowInTable', - deleteRowInTable = 'deleteRowInTable', - getRowByPrimaryKey = 'getRowByPrimaryKey', - bulkGetRowsFromTableByPrimaryKeys = 'bulkGetRowsFromTableByPrimaryKeys', - getRowsFromTable = 'getRowsFromTable', - getTableForeignKeys = 'getTableForeignKeys', - getTablePrimaryColumns = 'getTablePrimaryColumns', - getTableStructure = 'getTableStructure', - getTablesFromDB = 'getTablesFromDB', - testConnect = 'testConnect', - updateRowInTable = 'updateRowInTable', - bulkUpdateRowsInTable = 'bulkUpdateRowsInTable', - bulkDeleteRowsInTable = 'bulkDeleteRowsInTable', - validateSettings = 'validateSettings', - getIdentityColumns = 'getIdentityColumns', - getReferencedTableNamesAndColumns = 'getReferencedTableNamesAndColumns', - isView = 'isView', - getRowsAsStream = 'getRowsAsStream', - executeRawQuery = 'executeRawQuery', + addRowInTable = 'addRowInTable', + deleteRowInTable = 'deleteRowInTable', + getRowByPrimaryKey = 'getRowByPrimaryKey', + bulkGetRowsFromTableByPrimaryKeys = 'bulkGetRowsFromTableByPrimaryKeys', + getRowsFromTable = 'getRowsFromTable', + getTableForeignKeys = 'getTableForeignKeys', + getTablePrimaryColumns = 'getTablePrimaryColumns', + getTableStructure = 'getTableStructure', + getTablesFromDB = 'getTablesFromDB', + testConnect = 'testConnect', + updateRowInTable = 'updateRowInTable', + bulkUpdateRowsInTable = 'bulkUpdateRowsInTable', + bulkDeleteRowsInTable = 'bulkDeleteRowsInTable', + validateSettings = 'validateSettings', + getIdentityColumns = 'getIdentityColumns', + getReferencedTableNamesAndColumns = 'getReferencedTableNamesAndColumns', + isView = 'isView', + getRowsAsStream = 'getRowsAsStream', + executeRawQuery = 'executeRawQuery', } diff --git a/shared-code/src/shared/enums/filter-criteria.enum.ts b/shared-code/src/shared/enums/filter-criteria.enum.ts index f99215200..85b725133 100644 --- a/shared-code/src/shared/enums/filter-criteria.enum.ts +++ b/shared-code/src/shared/enums/filter-criteria.enum.ts @@ -1,12 +1,12 @@ export enum FilterCriteriaEnum { - startswith = 'startswith', - endswith = 'endswith', - gt = 'gt', - lt = 'lt', - lte = 'lte', - gte = 'gte', - contains = 'contains', - icontains = 'icontains', - eq = 'eq', - empty = 'empty' -} \ No newline at end of file + startswith = 'startswith', + endswith = 'endswith', + gt = 'gt', + lt = 'lt', + lte = 'lte', + gte = 'gte', + contains = 'contains', + icontains = 'icontains', + eq = 'eq', + empty = 'empty', +} diff --git a/shared-code/src/shared/enums/query-ordering.enum.ts b/shared-code/src/shared/enums/query-ordering.enum.ts index 79cedd74e..af68dc388 100644 --- a/shared-code/src/shared/enums/query-ordering.enum.ts +++ b/shared-code/src/shared/enums/query-ordering.enum.ts @@ -1,4 +1,4 @@ export enum QueryOrderingEnum { - ASC = 'ASC', - DESC = 'DESC', + ASC = 'ASC', + DESC = 'DESC', } diff --git a/shared-code/src/shared/enums/table-widget-type.enum.ts b/shared-code/src/shared/enums/table-widget-type.enum.ts index 12dd6a13a..ef58f18cd 100644 --- a/shared-code/src/shared/enums/table-widget-type.enum.ts +++ b/shared-code/src/shared/enums/table-widget-type.enum.ts @@ -1,26 +1,26 @@ export enum TableWidgetTypeEnum { - Password = 'Password', - Boolean = 'Boolean', - Date = 'Date', - Time = 'Time', - DateTime = 'DateTime', - JSON = 'JSON', - Textarea = 'Textarea', - String = 'String', - Readonly = 'Readonly', - Number = 'Number', - Select = 'Select', - UUID = 'UUID', - Enum = 'Enum', - Foreign_key = 'Foreign_key', - File = 'File', - Image = 'Image', - URL = 'URL', - Code = 'Code', - Phone = 'Phone', - Country = 'Country', - Color = 'Color', - Range = 'Range', - Timezone = 'Timezone', - S3 = 'S3', + Password = 'Password', + Boolean = 'Boolean', + Date = 'Date', + Time = 'Time', + DateTime = 'DateTime', + JSON = 'JSON', + Textarea = 'Textarea', + String = 'String', + Readonly = 'Readonly', + Number = 'Number', + Select = 'Select', + UUID = 'UUID', + Enum = 'Enum', + Foreign_key = 'Foreign_key', + File = 'File', + Image = 'Image', + URL = 'URL', + Code = 'Code', + Phone = 'Phone', + Country = 'Country', + Color = 'Color', + Range = 'Range', + Timezone = 'Timezone', + S3 = 'S3', } diff --git a/shared-code/src/shared/interfaces/data-access-object-agent.interface.ts b/shared-code/src/shared/interfaces/data-access-object-agent.interface.ts index d233b9a38..eb6ce5533 100644 --- a/shared-code/src/shared/interfaces/data-access-object-agent.interface.ts +++ b/shared-code/src/shared/interfaces/data-access-object-agent.interface.ts @@ -12,101 +12,101 @@ import { ValidateTableSettingsDS } from '../../data-access-layer/shared/data-str import { Stream } from 'node:stream'; export interface IDataAccessObjectAgent { - addRowInTable( - tableName: string, - row: Record, - userEmail: string, - ): Promise | number>; - - deleteRowInTable( - tableName: string, - primaryKey: Record, - userEmail: string, - ): Promise>; - - getIdentityColumns( - tableName: string, - referencedFieldName: string, - identityColumnName: string, - fieldValues: Array, - userEmail: string, - ): Promise>>; - - getRowByPrimaryKey( - tableName: string, - primaryKey: Record, - settings: TableSettingsDS, - userEmail: string, - ): Promise>; - - bulkGetRowsFromTableByPrimaryKeys( - tableName: string, - primaryKeys: Array>, - settings: TableSettingsDS, - userEmail: string, - ): Promise>>; - - getRowsFromTable( - tableName: string, - settings: TableSettingsDS, - page: number, - perPage: number, - searchedFieldValue: string, - filteringFields: Array, - autocompleteFields: AutocompleteFieldsDS, - tableStructure: TableStructureDS[] | null, - userEmail: string, - ): Promise; - - getTableForeignKeys(tableName: string, userEmail: string): Promise>; - - getTablePrimaryColumns(tableName: string, userEmail: string): Promise>; - - getTablesFromDB(userEmail?: string): Promise>; - - getTableStructure(tableName: string, userEmail: string): Promise>; - - testConnect(): Promise; - - updateRowInTable( - tableName: string, - row: Record, - primaryKey: Record, - userEmail: string, - ): Promise>; - - bulkUpdateRowsInTable( - tableName: string, - newValues: Record, - primaryKeys: Array>, - userEmail: string, - ): Promise>>; - - bulkDeleteRowsInTable( - tableName: string, - primaryKeys: Array>, - userEmail: string, - ): Promise; - - validateSettings(settings: ValidateTableSettingsDS, tableName: string, userEmail: string): Promise>; - - getReferencedTableNamesAndColumns( - tableName: string, - userEmail: string, - ): Promise>; - - isView(tableName: string, userEmail: string): Promise; - - getTableRowsStream( - tableName: string, - settings: TableSettingsDS, - page: number, - perPage: number, - searchedFieldValue: string, - filteringFields: Array, - ): Promise>; - - importCSVInTable(file: Express.Multer.File, tableName: string, userEmail: string): Promise; - - executeRawQuery(query: string, tableName: string, userEmail: string): Promise>>; + addRowInTable( + tableName: string, + row: Record, + userEmail: string, + ): Promise | number>; + + deleteRowInTable( + tableName: string, + primaryKey: Record, + userEmail: string, + ): Promise>; + + getIdentityColumns( + tableName: string, + referencedFieldName: string, + identityColumnName: string, + fieldValues: Array, + userEmail: string, + ): Promise>>; + + getRowByPrimaryKey( + tableName: string, + primaryKey: Record, + settings: TableSettingsDS, + userEmail: string, + ): Promise>; + + bulkGetRowsFromTableByPrimaryKeys( + tableName: string, + primaryKeys: Array>, + settings: TableSettingsDS, + userEmail: string, + ): Promise>>; + + getRowsFromTable( + tableName: string, + settings: TableSettingsDS, + page: number, + perPage: number, + searchedFieldValue: string, + filteringFields: Array, + autocompleteFields: AutocompleteFieldsDS, + tableStructure: TableStructureDS[] | null, + userEmail: string, + ): Promise; + + getTableForeignKeys(tableName: string, userEmail: string): Promise>; + + getTablePrimaryColumns(tableName: string, userEmail: string): Promise>; + + getTablesFromDB(userEmail?: string): Promise>; + + getTableStructure(tableName: string, userEmail: string): Promise>; + + testConnect(): Promise; + + updateRowInTable( + tableName: string, + row: Record, + primaryKey: Record, + userEmail: string, + ): Promise>; + + bulkUpdateRowsInTable( + tableName: string, + newValues: Record, + primaryKeys: Array>, + userEmail: string, + ): Promise>>; + + bulkDeleteRowsInTable( + tableName: string, + primaryKeys: Array>, + userEmail: string, + ): Promise; + + validateSettings(settings: ValidateTableSettingsDS, tableName: string, userEmail: string): Promise>; + + getReferencedTableNamesAndColumns( + tableName: string, + userEmail: string, + ): Promise>; + + isView(tableName: string, userEmail: string): Promise; + + getTableRowsStream( + tableName: string, + settings: TableSettingsDS, + page: number, + perPage: number, + searchedFieldValue: string, + filteringFields: Array, + ): Promise>; + + importCSVInTable(file: Express.Multer.File, tableName: string, userEmail: string): Promise; + + executeRawQuery(query: string, tableName: string, userEmail: string): Promise>>; } diff --git a/shared-code/src/shared/interfaces/data-access-object.interface.ts b/shared-code/src/shared/interfaces/data-access-object.interface.ts index ede9cae82..a62c9ccc4 100644 --- a/shared-code/src/shared/interfaces/data-access-object.interface.ts +++ b/shared-code/src/shared/interfaces/data-access-object.interface.ts @@ -12,80 +12,80 @@ import { TableDS } from '../../data-access-layer/shared/data-structures/table.ds import { Stream } from 'node:stream'; export interface IDataAccessObject { - addRowInTable(tableName: string, row: Record): Promise | number>; + addRowInTable(tableName: string, row: Record): Promise | number>; - deleteRowInTable(tableName: string, primaryKey: Record): Promise>; + deleteRowInTable(tableName: string, primaryKey: Record): Promise>; - getIdentityColumns( - tableName: string, - referencedFieldName: string, - identityColumnName: string, - fieldValues: Array, - ): Promise>>; + getIdentityColumns( + tableName: string, + referencedFieldName: string, + identityColumnName: string, + fieldValues: Array, + ): Promise>>; - getRowByPrimaryKey( - tableName: string, - primaryKey: Record, - settings: TableSettingsDS, - ): Promise>; + getRowByPrimaryKey( + tableName: string, + primaryKey: Record, + settings: TableSettingsDS, + ): Promise>; - bulkGetRowsFromTableByPrimaryKeys( - tableName: string, - primaryKeys: Array>, - settings: TableSettingsDS, - ): Promise>>; + bulkGetRowsFromTableByPrimaryKeys( + tableName: string, + primaryKeys: Array>, + settings: TableSettingsDS, + ): Promise>>; - getRowsFromTable( - tableName: string, - settings: TableSettingsDS, - page: number, - perPage: number, - searchedFieldValue: string, - filteringFields: Array, - autocompleteFields: AutocompleteFieldsDS, - tableStructure: TableStructureDS[] | null, - ): Promise; + getRowsFromTable( + tableName: string, + settings: TableSettingsDS, + page: number, + perPage: number, + searchedFieldValue: string, + filteringFields: Array, + autocompleteFields: AutocompleteFieldsDS, + tableStructure: TableStructureDS[] | null, + ): Promise; - getTableForeignKeys(tableName: string): Promise>; + getTableForeignKeys(tableName: string): Promise>; - getTablePrimaryColumns(tableName: string): Promise>; + getTablePrimaryColumns(tableName: string): Promise>; - getTablesFromDB(): Promise>; + getTablesFromDB(): Promise>; - getTableStructure(tableName: string): Promise>; + getTableStructure(tableName: string): Promise>; - testConnect(): Promise; + testConnect(): Promise; - updateRowInTable( - tableName: string, - row: Record, - primaryKey: Record, - ): Promise>; + updateRowInTable( + tableName: string, + row: Record, + primaryKey: Record, + ): Promise>; - bulkUpdateRowsInTable( - tableName: string, - newValues: Record, - primaryKeys: Array>, - ): Promise>>; + bulkUpdateRowsInTable( + tableName: string, + newValues: Record, + primaryKeys: Array>, + ): Promise>>; - bulkDeleteRowsInTable(tableName: string, primaryKeys: Array>): Promise; + bulkDeleteRowsInTable(tableName: string, primaryKeys: Array>): Promise; - validateSettings(settings: ValidateTableSettingsDS, tableName: string): Promise>; + validateSettings(settings: ValidateTableSettingsDS, tableName: string): Promise>; - getReferencedTableNamesAndColumns(tableName: string): Promise>; + getReferencedTableNamesAndColumns(tableName: string): Promise>; - isView(tableName: string): Promise; + isView(tableName: string): Promise; - getTableRowsStream( - tableName: string, - settings: TableSettingsDS, - page: number, - perPage: number, - searchedFieldValue: string, - filteringFields: Array, - ): Promise>; + getTableRowsStream( + tableName: string, + settings: TableSettingsDS, + page: number, + perPage: number, + searchedFieldValue: string, + filteringFields: Array, + ): Promise>; - importCSVInTable(file: Express.Multer.File, tableName: string): Promise; + importCSVInTable(file: Express.Multer.File, tableName: string): Promise; - executeRawQuery(query: string, tableName: string): Promise>>; + executeRawQuery(query: string, tableName: string): Promise>>; } diff --git a/shared-code/src/shared/interfaces/unknown-datastructure.interface.ts b/shared-code/src/shared/interfaces/unknown-datastructure.interface.ts index 83afc93f6..dbc719538 100644 --- a/shared-code/src/shared/interfaces/unknown-datastructure.interface.ts +++ b/shared-code/src/shared/interfaces/unknown-datastructure.interface.ts @@ -1,3 +1,3 @@ export interface IUnknownDataStructure { - [key: string]: any; -} \ No newline at end of file + [key: string]: any; +}